Co je a LATERAL
připojit se?
Tato funkce byla představena s PostgreSQL 9.3. Manuál:
Dílčí dotazy zobrazené v
FROM
může předcházet klíčové slovoLATERAL
. To jim umožňuje odkazovat na sloupce poskytnuté předchozímFROM
položky. (BezLATERAL
, je každý poddotaz vyhodnocen nezávisle, a tak nemůže křížově odkazovat na žádný jinýFROM
položka.)Tabulkové funkce zobrazené v
FROM
můž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ímFROM
polož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
FROM
dolož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
INNER
aOUTER
typu spojení, musí být specifikována podmínka spojení, a to přesně jedna zNATURAL
,ON
join_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.