Co je a LATERAL připojit se?
Tato funkce byla představena s PostgreSQL 9.3. Manuál:
Dílčí dotazy zobrazené v
FROMmůže předcházet klíčové slovoLATERAL. To jim umožňuje odkazovat na sloupce poskytnuté předchozímFROMpoložky. (BezLATERAL, je každý poddotaz vyhodnocen nezávisle, a tak nemůže křížově odkazovat na žádný jinýFROMpoložka.)Tabulkové funkce zobrazené v
FROMmůže také předcházet klíčové slovoLATERAL, ale pro funkce je klíčové slovo nepovinné; argumenty funkce mohou obsahovat odkazy na sloupce poskytnuté předřazenímFROMpoložky v každém případě.
Jsou zde uvedeny základní příklady kódu.
Spíš jako korelovaný dílčí dotaz
A LATERAL join je spíše jako korelovaný poddotaz, nikoli prostý poddotaz, v tom výrazy napravo od LATERAL join jsou vyhodnoceny jednou pro každý řádek vlevo od něj – stejně jako korelované poddotaz - zatímco prostý poddotaz (tabulkový výraz) je vyhodnocen jednou pouze. (Plánovač dotazů však nabízí způsoby, jak optimalizovat výkon pro oba.)
Související odpověď s příklady kódu pro oba vedle sebe, řešící stejný problém:
- Optimalizujte dotaz GROUP BY pro načtení posledního řádku na uživatele
Pro vrácení více než jednoho sloupce , LATERAL join je obvykle jednodušší, čistší a rychlejší.
Nezapomeňte také, že ekvivalentem korelovaného dílčího dotazu je LEFT JOIN LATERAL ... ON true :
- Volejte funkci vracející sadu s argumentem pole vícekrát
Věci, které dílčí dotaz neumí
jsou věci, které LATERAL join umí, ale (související) poddotaz ne (snadno). Korelovaný poddotaz může vrátit pouze jednu hodnotu, nikoli více sloupců a ne více řádků – s výjimkou volání holých funkcí (která znásobí řádky výsledků, pokud vrátí více řádků). Ale i určité funkce vracející sadu jsou povoleny pouze v FROM doložka. Jako unnest() s více parametry v Postgres 9.4 nebo novější. Manuál:
To je povoleno pouze v
FROMdoložka;
Takže to funguje, ale nelze (snadno) nahradit poddotazem:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Čárka (, ) v FROM klauzule je krátký zápis pro CROSS JOIN .LATERAL se u tabulkových funkcí předpokládá automaticky.
O speciálním případě UNNEST( array_expression [, ... ] ) :
- Jak deklarujete, že funkce set-returning- bude povolena pouze v klauzuli FROM?
Nastavte funkce vracení v SELECT seznam
Můžete také použít funkce vracející sadu, jako je unnest() v SELECT vypsat přímo. To se projevovalo překvapivým chováním s více než jednou takovou funkcí ve stejném SELECT seznam až do Postgresu 9.6. Ale konečně byl dezinfikován pomocí Postgres 10 a je nyní platnou alternativou (i když ne standardní SQL). Viz:
- Jaké je očekávané chování pro více funkcí vracejících sadu v klauzuli SELECT?
Na základě výše uvedeného příkladu:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
Srovnání:
dbfiddle pro pg 9.6 zde
dbfiddle pro pg 10 zde
Objasněte dezinformace
Manuál:
Pro
INNERaOUTERtypu spojení, musí být specifikována podmínka spojení, a to přesně jedna zNATURAL,ONjoin_condition neboUSING(join_column [, ...]). Význam viz níže.
ProCROSS JOIN, žádná z těchto klauzulí se nemůže objevit.
Takže tyto dva dotazy jsou platné (i když nejsou nijak zvlášť užitečné):
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t ON TRUE;
SELECT *
FROM tbl t, LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Zatímco tento není:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
To je důvod, proč je příklad kódu Andomar správný (CROSS JOIN nevyžaduje podmínku připojení) a Attilův je nebyl.