Daha çok ilişkili bir alt sorgu gibi
Bir LATERAL
(Postgres 9.3 veya üzeri) daha fazla gibi birleştirme ilişkili alt sorgu , bir düz alt sorgu. Andomar'ın işaret ettiği gibi , LATERAL
birleştirmenin sağındaki bir işlev veya alt sorgu, soldaki her satır için bir kez değerlendirilmelidir - tıpkı ilişkili bir alt sorgu gibi - düz bir alt sorgu (tablo ifadesi) yalnızca bir kez değerlendirilir . (Sorgu planlayıcısının,
her ikisi için de performansı optimize etmenin yolları vardır.) Bu ilgili yanıt, aynı sorunu çözerek her iki taraf için de kod örneklerine sahiptir:
Birden fazla sütun döndürmek için bir LATERAL
birleştirme genellikle daha basit, daha temiz ve daha hızlıdır.
Ayrıca, ilişkili bir alt sorgunun eşdeğeri olduğunu unutmayın LEFT JOIN LATERAL ... ON true
:
Üzerindeki kılavuzu okuyun LATERAL
Burada cevaplara koyacağımız her şeyden daha otoriter:
Bir alt sorgunun yapamayacağı şeyler
Orada olan bir bu işler LATERAL
yapabilir katılmak, ancak bir (korelasyon) alt sorgu (kolayca) olamaz. İlişkili bir alt sorgu, çıplak işlev çağrıları (birden çok satır döndürürlerse sonuç satırlarını çoğaltır) hariç, yalnızca tek bir değer döndürür, birden çok sütun değil, birden çok satır döndüremez. Ancak bazı set-döndürme işlevlerine bile sadece FROM
maddede izin verilir . unnest()
Postgres 9.4 veya sonraki sürümlerde çoklu parametrelerde olduğu gibi . Kullanım kılavuzu:
Buna sadece FROM
maddede izin verilir ;
Bu işe yarar, ancak kolayca bir alt sorgu ile değiştirilemez:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
Madde içindeki virgül ( ,
) FROM
kısa gösterimdir CROSS JOIN
.
LATERAL
tablo işlevleri için otomatik olarak kabul edilir.
Özel durum hakkında daha fazla bilgi UNNEST( array_expression [, ... ] )
:
SELECT
Listedeki geri dönen işlevler
Ayrıca gibi set dönen işlevleri kullanabilirsiniz unnest()
içinde SELECT
doğrudan listeye. Bu, aynı SELECT
listede Postgres 9.6'ya kadar birden fazla işlevle şaşırtıcı davranışlar sergilemek için kullanılır . Ancak sonunda Postgres 10 ile sterilize edildi ve şu anda geçerli bir alternatif (standart SQL olmasa bile). Görmek:
Yukarıdaki örneğe dayanarak:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
karşılaştırma:
pg 9.6 için dbfiddle burada
pg 10 dbfiddle burada
Yanlış bilgileri netleştirin
Kullanım kılavuzu:
İçin INNER
ve OUTER
birleştirme türleri, bir durumdur, yani tam olarak biri belirtilmelidir katılması NATURAL
, ON
join_condition veya USING
( join_column [...]). Anlam için aşağıya bakın.
Çünkü CROSS JOIN
, bu maddelerin hiçbiri görünmez.
Dolayısıyla bu iki sorgu geçerlidir (özellikle yararlı olmasa bile):
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;
Bu olmasa da:
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
Bu yüzden Andomar en @ kod örneği doğrudur ( CROSS JOIN
bir birleşim koşulu gerektirmez) ve Attila'nın @ DİR geçersiz oldu.
apply
aynıdırlateral
)