WITH
consente di definire "tabelle temporanee" per l'utilizzo in una query SELECT
. Ad esempio, recentemente ho scritto una query come questa, per calcolare i cambiamenti tra i due gruppi:
-- Let o be the set of old things, and n be the set of new things.
WITH o AS (SELECT * FROM things(OLD)),
n AS (SELECT * FROM things(NEW))
-- Select both the set of things whose value changed,
-- and the set of things in the old set but not in the new set.
SELECT o.key, n.value
FROM o
LEFT JOIN n ON o.key = n.key
WHERE o.value IS DISTINCT FROM n.value
UNION ALL
-- Select the set of things in the new set but not in the old set.
SELECT n.key, n.value
FROM o
RIGHT JOIN n ON o.key = n.key
WHERE o.key IS NULL;
Definendo i "tavoli" o
e n
in alto, ho potuto evitare di ripetere le espressioni things(OLD)
e things(NEW)
.
Certo, potremmo probabilmente eliminare il UNION ALL
utilizzando un FULL JOIN
, ma non ero in grado di farlo nel mio caso particolare.
Se ho capito bene la tua ricerca, lo fa:
Trova la più antica fila global.prospect il cui stato è 'nuovo' o 'reset'.
Mark con l'aggiunta di un asterisco per il suo status di
ritorno della fila (compreso il nostro tweak per status
).
Non credo che WITH
semplificherà nulla nel tuo caso. Può essere un po 'più elegante di utilizzare una clausola FROM
, però:
update global.prospect psp
set status = status || '*'
from (select psp_id
from global.prospect
where status = 'new' or status = 'reset'
order by request_ts
limit 1
) p2
where psp.psp_id = p2.psp_id
returning psp.*;
testato. Fammi sapere se funziona.
E 'più o meno esattamente quello che hai già, ad eccezione di:
Questo può essere facilmente esteso per aggiornare più righe. Nella tua versione, che utilizza un'espressione sottoquery, la query fallirebbe se la sottoquery venisse modificata per generare più righe.
Non ho indicato il valore global.prospect
nella sottoquery, quindi è un po 'più facile da leggere. Poiché utilizza una clausola FROM
, verrà visualizzato un errore se si fa accidentalmente riferimento alla tabella che si sta aggiornando.
Nella versione, l'espressione di sottoquery viene rilevata per ogni singolo elemento. Sebbene PostgreSQL debba ottimizzare questo aspetto e valutare l'espressione solo una volta, questa ottimizzazione scompare se si fa riferimento accidentalmente a una colonna in psp
o si aggiunge un'espressione volatile.
fonte
2012-01-04 04:06:02
Secondo la documentazione, l'uso di 'WITH [RECURSIVE]' sopra 'INSERT' e' UPDATE' è stato aggiunto in PostgreSQL 9.1. –
@JoeyAdams - usando con dml - un altro livello della cipolla per capire –