क्या है एक LATERAL
शामिल हों?
फीचर को PostgreSQL 9.3 के साथ पेश किया गया था। मैनुअल:
<ब्लॉकक्वॉट>
FROM
. में दिखाई देने वाली उपश्रेणियां कुंजी शब्द से पहले किया जा सकता हैLATERAL
. यह उन्हें पूर्ववर्तीFROM
. द्वारा प्रदान किए गए कॉलम को संदर्भित करने की अनुमति देता है सामान। (बिना LATERAL
, प्रत्येक सबक्वेरी का स्वतंत्र रूप से मूल्यांकन किया जाता है और इसलिए किसी अन्य FROM
से क्रॉस-रेफरेंस नहीं किया जा सकता है आइटम।)
FROM
. में दिखने वाले टेबल फ़ंक्शन कीवर्ड LATERAL
. से पहले भी हो सकते हैं , लेकिन कार्यों के लिए कुंजी शब्द वैकल्पिक है; फ़ंक्शन के तर्कों में FROM
. से पहले दिए गए कॉलम के संदर्भ शामिल हो सकते हैं किसी भी मामले में आइटम।
मूल कोड उदाहरण वहां दिए गए हैं।
अधिक एक सहसंबंधित की तरह सबक्वेरी
एक LATERAL
join एक सहसंबद्ध उपश्रेणी की तरह है, एक सादा उपश्रेणी नहीं, उस भाव में LATERAL
के दाईं ओर जॉइन का मूल्यांकन इसके बाईं ओर की प्रत्येक पंक्ति के लिए एक बार किया जाता है - जैसे सहसंबद्ध सबक्वेरी - जबकि एक प्लेन सबक्वेरी (टेबल एक्सप्रेशन) का मूल्यांकन एक बार किया जाता है केवल। (क्वेरी प्लानर के पास दोनों में से किसी के लिए भी प्रदर्शन को अनुकूलित करने के तरीके हैं।)
एक ही समस्या को हल करने के लिए दोनों तरफ कोड उदाहरणों के साथ संबंधित उत्तर:
- प्रति उपयोगकर्ता नवीनतम पंक्ति पुनर्प्राप्त करने के लिए क्वेरी द्वारा GROUP को अनुकूलित करें
एक से अधिक कॉलम returning लौटाने के लिए , एक LATERAL
शामिल होना आम तौर पर सरल, साफ और तेज़ होता है।
साथ ही, याद रखें कि एक सहसंबद्ध सबक्वेरी के बराबर LEFT JOIN LATERAL ... ON true
है :
- एक सरणी तर्क के साथ एक सेट-रिटर्निंग फ़ंक्शन को कई बार कॉल करें
वे चीज़ें जो एक सबक्वेरी नहीं कर सकती हैं
वहाँ हैं चीजें जो एक LATERAL
शामिल हो सकते हैं, लेकिन एक (सहसंबंधित) सबक्वेरी (आसानी से) नहीं कर सकता। एक सहसंबद्ध उपश्रेणी केवल एक मान लौटा सकती है, न कि कई कॉलम और न ही कई पंक्तियाँ - नंगे फ़ंक्शन कॉल के अपवाद के साथ (जो कई पंक्तियों को वापस करने पर परिणाम पंक्तियों को गुणा करती हैं)। लेकिन यहां तक कि कुछ सेट‑रिटर्निंग फ़ंक्शंस की अनुमति केवल FROM
. में है खंड। जैसे unnest()
Postgres 9.4 या बाद के कई मापदंडों के साथ। मैनुअल:
इसकी अनुमति केवल FROM
. में है खंड;
तो यह काम करता है, लेकिन (आसानी से) एक सबक्वेरी से बदला नहीं जा सकता:
CREATE TABLE tbl (a1 int[], a2 int[]);
SELECT * FROM tbl, unnest(a1, a2) u(elem1, elem2); -- implicit LATERAL
अल्पविराम (,
) FROM
. में क्लॉज CROSS JOIN
के लिए संक्षिप्त संकेत है .LATERAL
तालिका कार्यों के लिए स्वचालित रूप से माना जाता है।UNNEST( array_expression [, ... ] )
के विशेष मामले के बारे में :
- आप कैसे घोषित करते हैं कि सेट-रिटर्निंग-फ़ंक्शन केवल FROM क्लॉज़ में अनुमत है?
सेट-रिटर्न फ़ंक्शन SELECT
में हैं सूची
आप unnest()
. जैसे सेट-रिटर्निंग फ़ंक्शंस का भी उपयोग कर सकते हैं SELECT
. में सीधे सूची। यह एक ही SELECT
. में एक से अधिक ऐसे फ़ंक्शन के साथ आश्चर्यजनक व्यवहार प्रदर्शित करता था पोस्टग्रेज 9.6 तक की सूची। लेकिन इसे अंततः पोस्टग्रेज 10 के साथ साफ कर दिया गया है और अब यह एक वैध विकल्प है (भले ही मानक एसक्यूएल न हो)। देखें:
- सेलेक्ट क्लॉज में कई सेट-रिटर्निंग फंक्शन के लिए अपेक्षित व्यवहार क्या है?
उपरोक्त उदाहरण पर निर्माण:
SELECT *, unnest(a1) AS elem1, unnest(a2) AS elem2
FROM tbl;
तुलना:
dbfiddle पृष्ठ 9.6 के लिए यहां
dbfiddle पृष्ठ 10 के लिए यहां
गलत जानकारी स्पष्ट करें
मैनुअल:
<ब्लॉकक्वॉट>
INNER
. के लिए और OUTER
जॉइन प्रकार, एक जॉइन कंडीशन को निर्दिष्ट किया जाना चाहिए, अर्थात् बिल्कुल NATURAL
. में से एक , ON
join_condition , या USING
(join_column [, ...])। अर्थ के लिए नीचे देखें।CROSS JOIN
के लिए , इनमें से कोई भी खंड प्रकट नहीं हो सकता है।
तो ये दो प्रश्न मान्य हैं (भले ही विशेष रूप से उपयोगी न हों):
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;
जबकि यह नहीं है:
<स्ट्राइक>
SELECT *
FROM tbl t
LEFT JOIN LATERAL (SELECT * FROM b WHERE b.t_id = t.t_id) t;
स्ट्राइक>
इसलिए एंडोमर का कोड उदाहरण सही है (CROSS JOIN
शामिल होने की शर्त की आवश्यकता नहीं है) और अत्तिला की <स्ट्राइक>हैस्ट्राइक> नहीं था।