Základní odpověď
Existují CTE (Common Table Expressions) v Postgres (jako v každém velkém moderním RDBMS kromě MySQL). Od verze 9.1, která zahrnuje CTE upravující data. Ty lze „vnořit“.
Aktualizace:MySQL 8.0 konečně přidává CTE.
Na rozdíl od poddotazů CTE představují optimalizační bariéry. Plánovač dotazů nemůže vkládat triviální příkazy do hlavního příkazu nebo měnit pořadí spojení mezi hlavním dotazem a CTE. Totéž je možné s poddotazy. Může být (velmi) dobrý nebo (velmi) špatný z hlediska výkonu, to záleží.
V každém případě vyžadují CTE o něco větší režii (náklady na výkon) než dílčí dotazy.
Aktualizace:Postgres 12 může konečně vkládat prosté CTE v hlavním dotazu.
Podrobnosti, na které jste se neptali
Vaše otázka je velmi základní, výše uvedené pravděpodobně stačí k zodpovězení. Ale přidám trochu pro pokročilé uživatele (a příklad kódu pro ukázku syntaxe).
Všechny CTE dotazu jsou založeny na stejném snímku databáze. Další CTE může znovu použít výstup předchozích CTE (interní dočasné tabulky), ale účinky na podkladové tabulky jsou pro ostatní CTE neviditelné. Posloupnost více CTE je libovolná pokud něco je vráceno pomocí RETURNING
klauzule pro INSERT
, UPDATE
, DELETE
- irelevantní pro SELECT
, protože nic nemění a pouze čte ze snímku.
To může mít jemné efekty s více aktualizacemi, které by ovlivnily stejný řádek. Pouze jeden aktualizace může ovlivnit každý řádek. Který z nich je ovlivněn posloupností CTE.
Zkuste předpovědět výsledek:
CREATE TEMP TABLE t (t_id int, txt text);
INSERT INTO t VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');
WITH sel AS (SELECT * FROM t)
, up1 AS (UPDATE t SET txt = txt || '1' WHERE t_id = 1 RETURNING *)
, up2 AS (UPDATE t SET txt = t.txt || '2'
FROM up1
WHERE up1.t_id = t.t_id
RETURNING t.*)
, ins AS (INSERT INTO t VALUES (4, 'bamm'))
, up3 AS (UPDATE t SET txt = txt || '3' RETURNING *)
SELECT 'sel' AS source, * FROM sel
UNION ALL
SELECT 'up1' AS source, * FROM up1
UNION ALL
SELECT 'up2' AS source, * FROM up2
UNION ALL
SELECT 'up3' AS source, * FROM up3
UNION ALL
SELECT 't' AS source, * FROM t;
SQL Fiddle
Nebuďte zklamaní, pochybuji, že je tu mnoho těch, kteří to dokázali. :)
Podstata toho:vyhnout se konfliktní příkazy v CTE.