पोस्टग्रेज में 9.3 या बाद में इसे LATERAL
. के साथ सबसे अच्छा हल किया जाता है शामिल हों:
SELECT *
FROM actors a
JOIN movies_actors ma on a.actor_id = ma.movie_id
LEFT JOIN LATERAL hi_lo(a.actor_id, length(a.name), ma.movie_id) x ON true
LIMIT 10;
फ़ंक्शन के बार-बार मूल्यांकन से बचा जाता है (आउटपुट में प्रत्येक कॉलम के लिए - प्रत्येक इनपुट पंक्ति के लिए फ़ंक्शन को किसी भी तरह से कॉल करना पड़ता है)।LEFT JOIN LATERAL ... ON true
यदि फ़ंक्शन कोई पंक्ति नहीं लौटाता है, तो बाईं ओर से पंक्तियों को छोड़ने से बचने के लिए:
- पोस्टग्रेएसक्यूएल में लेटरल और सबक्वेरी में क्या अंतर है?
अपनी टिप्पणी में अनुवर्ती कार्रवाई करें:
<ब्लॉककोट>फ़ंक्शन कॉल द्वारा निर्मित केवल विस्तारित कॉलम
SELECT x.* -- that's all!
FROM actors a
JOIN movies_actors ma on a.actor_id = ma.movie_id
LEFT JOIN LATERAL hi_lo(a.actor_id, length(a.name), ma.movie_id) x ON true
LIMIT 10;
लेकिन चूंकि आप अन्य स्तंभों की परवाह नहीं करते हैं, इसलिए आप इसे आसान बना सकते हैं:
SELECT x.*
FROM actors a
JOIN movies_actors ma on a.actor_id = ma.movie_id
, hi_lo(a.actor_id, length(a.name), ma.movie_id) x
LIMIT 10;
जो एक निहित CROSS JOIN LATERAL
. है . यदि फ़ंक्शन वास्तव में कभी-कभी "कोई पंक्ति नहीं" लौटा सकता है, तो परिणाम भिन्न हो सकता है:हमें पंक्तियों के लिए NULL मान नहीं मिलते हैं, उन पंक्तियों को बस समाप्त कर दिया जाता है - और LIMIT
अब उनकी गिनती नहीं करता।
पुराने संस्करणों में (या आम तौर पर) आप सही सिंटैक्स के साथ समग्र प्रकार को भी विघटित कर सकते हैं:
SELECT *, (hi_lo(a.actor_id, length(a.name), ma.movie_id)).* -- note extra parentheses!
FROM actors a
JOIN movies_actors ma on a.actor_id = ma.movie_id
LIMIT 10;
दोष यह है कि पोस्टग्रेज क्वेरी प्लानर में कमजोरी के कारण फ़ंक्शन आउटपुट में प्रत्येक कॉलम के लिए फ़ंक्शन का मूल्यांकन एक बार किया जाता है। कॉल को एक सबक्वायरी या सीटीई में ले जाना और पंक्ति प्रकार को बाहरी SELECT
में विघटित करना बेहतर है . पसंद:
SELECT actor_id, movie_id, (x).* -- explicit column names for the rest
FROM (
SELECT *, hi_lo(a.actor_id, length(a.name), ma.movie_id) AS x
FROM actors a
JOIN movies_actors ma on a.actor_id = ma.movie_id
LIMIT 10
) sub;
लेकिन आपको अलग-अलग स्तंभों को नाम देना होगा और SELECT *
. के साथ दूर नहीं जा सकते जब तक कि आप अनावश्यक रूप से परिणाम में पंक्ति प्रकार के साथ ठीक न हों। संबंधित:
- समग्र परिणाम का विस्तार करते समय एक ही फ़ंक्शन पर एकाधिक कॉल से बचें
- एक SQL क्वेरी में (func()).* सिंटैक्स के साथ कई फ़ंक्शन evals से कैसे बचें?