आम तौर पर, पंक्तियों को विघटित करने के लिए किसी फ़ंक्शन से लौटा और अलग-अलग कॉलम प्राप्त करें:
SELECT * FROM account_servicetier_for_day(20424, '2014-08-12');
क्वेरी के लिए:
9.3 या नए को पोस्ट करें
JOIN LATERAL
. के साथ क्लीनर :
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
, a.username, a.accountid, a.userid
, f.* -- but avoid duplicate column names!
FROM account_tab a
, account_servicetier_for_day(a.accountid, '2014-08-12') f -- <-- HERE
WHERE a.isdsl = 1
AND a.dslservicetypeid IS NOT NULL
AND NOT EXISTS (
SELECT 1
FROM dailyaccounting_tab
WHERE day = '2014-08-12'
AND accountid = a.accountid
)
ORDER BY a.username;
LATERAL
कीवर्ड यहां निहित है, फ़ंक्शन हमेशा पहले FROM
का उल्लेख कर सकते हैं सामान। मैनुअल:
LATERAL
फ़ंक्शन-कॉल से पहले FROM
. भी हो सकता है आइटम, लेकिन इस मामले में यह एक शोर शब्द है, क्योंकि फ़ंक्शन अभिव्यक्ति पहले FROM
को संदर्भित कर सकती है किसी भी मामले में आइटम।
संबंधित:
- किसी अन्य तालिका में संख्या के आधार पर एक तालिका में एकाधिक पंक्तियों को सम्मिलित करें
FROM
. में अल्पविराम के साथ संक्षिप्त संकेतन सूची (ज्यादातर) CROSS JOIN LATERAL
. के बराबर है (समान [INNER] JOIN LATERAL ... ON TRUE
) और इस प्रकार परिणाम से पंक्तियों को हटा देता है जहां फ़ंक्शन कॉल कोई पंक्ति नहीं देता है। ऐसी पंक्तियों को बनाए रखने के लिए, LEFT JOIN LATERAL ... ON TRUE
का उपयोग करें :
...
FROM account_tab a
LEFT JOIN LATERAL account_servicetier_for_day(a.accountid, '2014-08-12') f ON TRUE
...
साथ ही, NOT IN (subquery)
. का उपयोग न करें जब आप इससे बच सकते हैं। ऐसा करने के कई तरीकों में यह सबसे धीमा और सबसे कठिन है:
- उन पंक्तियों का चयन करें जो अन्य तालिका में मौजूद नहीं हैं
मेरा सुझाव है NOT EXISTS
इसके बजाय।
9.2 या पुराने को पोस्ट करें
आप SELECT
. में सेट-रिटर्निंग फ़ंक्शन को कॉल कर सकते हैं सूची (जो मानक SQL का एक पोस्टग्रेज एक्सटेंशन है)। प्रदर्शन कारणों से, यह सबक्वायरी में सबसे अच्छा किया जाता है। फ़ंक्शन के बार-बार मूल्यांकन से बचने के लिए बाहरी क्वेरी में (प्रसिद्ध!) पंक्ति प्रकार को विघटित करें:
SELECT '2014-08-12' AS day, 0 AS inbytes, 0 AS outbytes
, a.username, a.accountid, a.userid
, (a.rec).* -- but avoid duplicate column names!
FROM (
SELECT *, account_servicetier_for_day(a.accountid, '2014-08-12') AS rec
FROM account_tab a
WHERE a.isdsl = 1
AND a.dslservicetypeid Is Not Null
AND NOT EXISTS (
SELECT 1
FROM dailyaccounting_tab
WHERE day = '2014-08-12'
AND accountid = a.accountid
)
) a
ORDER BY a.username;
क्रेग रिंगर द्वारा एक स्पष्टीकरण के साथ संबंधित उत्तर, हम बाहरी क्वेरी में बेहतर तरीके से क्यों विघटित होते हैं:
- एक SQL क्वेरी में (func()).* सिंटैक्स के साथ एकाधिक फ़ंक्शन evals से कैसे बचें?
10 पोस्ट करता है SELECT
. में सेट-रिटर्निंग फ़ंक्शंस के व्यवहार में विषमताओं को दूर किया :
- सेलेक्ट क्लॉज में कई सेट-रिटर्निंग फंक्शन के लिए अपेक्षित व्यवहार क्या है?