PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL में किसी फ़ंक्शन के अंदर किसी चयन का परिणाम कैसे वापस करें?

RETURN QUERY . का उपयोग करें :

CREATE OR REPLACE FUNCTION word_frequency(_max_tokens int)
  RETURNS TABLE (txt   text   -- also visible as OUT parameter inside function
               , cnt   bigint
               , ratio bigint)
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY
   SELECT t.txt
        , count(*) AS cnt                 -- column alias only visible inside
        , (count(*) * 100) / _max_tokens  -- I added brackets
   FROM  (
      SELECT t.txt
      FROM   token t
      WHERE  t.chartype = 'ALPHABETIC'
      LIMIT  _max_tokens
      ) t
   GROUP  BY t.txt
   ORDER  BY cnt DESC;                    -- potential ambiguity 
END
$func$;

कॉल करें:

SELECT * FROM word_frequency(123);

वापसी प्रकार को स्पष्ट रूप से परिभाषित करना बहुत है सामान्य record returning लौटाने से अधिक व्यावहारिक . इस तरह आपको प्रत्येक फ़ंक्शन कॉल के साथ कॉलम परिभाषा सूची प्रदान करने की आवश्यकता नहीं है। RETURNS TABLE ऐसा करने का एक तरीका है। अन्य हैं। डेटा प्रकार OUT पैरामीटर को ठीक उसी तरह मेल खाना चाहिए जो क्वेरी द्वारा लौटाया जाता है।

OUT . के लिए नाम चुनें पैरामीटर सावधानी से। वे फंक्शन बॉडी में लगभग कहीं भी दिखाई देते हैं। विरोध या अनपेक्षित परिणामों से बचने के लिए समान नाम के तालिका-योग्य स्तंभ। मैंने अपने उदाहरण के सभी स्तंभों के लिए ऐसा किया है।

लेकिन संभावित नामकरण विरोध पर ध्यान दें OUT . के बीच पैरामीटर cnt और इसी नाम का स्तंभ उपनाम। इस विशेष मामले में (RETURN QUERY SELECT ... ) पोस्टग्रेज OUT . के ऊपर कॉलम एलियास का उपयोग करता है किसी भी तरह से पैरामीटर। हालांकि यह अन्य संदर्भों में अस्पष्ट हो सकता है। किसी भी भ्रम से बचने के कई तरीके हैं:

  1. चयन सूची में आइटम की क्रमिक स्थिति का उपयोग करें:ORDER BY 2 DESC . उदाहरण:
    • समूह द्वारा प्रत्येक समूह में पहली पंक्ति का चयन करें?
  2. अभिव्यक्ति को दोहराएं ORDER BY count(*)
  3. (यहां लागू नहीं है।) कॉन्फ़िगरेशन पैरामीटर सेट करें plpgsql.variable_conflict या विशेष कमांड का उपयोग करें #variable_conflict error | use_variable | use_column समारोह में। देखें:
    • फ़ंक्शन पैरामीटर और USING क्लॉज़ के साथ JOIN के परिणाम के बीच विरोध का नामकरण

कॉलम नामों के रूप में "पाठ" या "गिनती" का प्रयोग न करें। दोनों पोस्टग्रेज में उपयोग करने के लिए कानूनी हैं, लेकिन "गिनती" एक आरक्षित शब्द . है मानक SQL में और एक मूल फ़ंक्शन नाम और "पाठ" एक मूल डेटा प्रकार है। भ्रमित करने वाली त्रुटियां हो सकती हैं। मैं txt . का उपयोग करता हूं और cnt मेरे उदाहरणों में, आप अधिक स्पष्ट नाम चाहते हैं।

एक अनुपलब्ध ; जोड़ा गया और हेडर में सिंटैक्स त्रुटि को ठीक किया। (_max_tokens int) , नहीं (int maxTokens) - टाइप करें नाम . के बाद ।

पूर्णांक विभाजन के साथ काम करते समय, पूर्णांकन त्रुटि को कम करने के लिए पहले गुणा करना और बाद में विभाजित करना बेहतर होता है। या numeric . के साथ काम करें या एक फ़्लोटिंग पॉइंट प्रकार। नीचे देखें।

वैकल्पिक

मैं यही सोचता हूं आपकी क्वेरी वास्तव में इस तरह दिखनी चाहिए (प्रति टोकन एक सापेक्ष शेयर की गणना ):

CREATE OR REPLACE FUNCTION word_frequency(_max_tokens int)
  RETURNS TABLE (txt            text
               , abs_cnt        bigint
               , relative_share numeric)
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY
   SELECT t.txt, t.cnt
        , round((t.cnt * 100) / (sum(t.cnt) OVER ()), 2)  -- AS relative_share
   FROM  (
      SELECT t.txt, count(*) AS cnt
      FROM   token t
      WHERE  t.chartype = 'ALPHABETIC'
      GROUP  BY t.txt
      ORDER  BY cnt DESC
      LIMIT  _max_tokens
      ) t
   ORDER  BY t.cnt DESC;
END
$func$;

व्यंजक sum(t.cnt) OVER () एक विंडो फ़ंक्शन है। आप कर सकते थे सबक्वायरी के बजाय सीटीई का प्रयोग करें। सुंदर, लेकिन इस तरह के साधारण मामलों में एक सबक्वेरी आमतौर पर सस्ता होता है (ज्यादातर पोस्टग्रेज 12 से पहले)।

एक अंतिम स्पष्ट RETURN कथन नहीं है OUT . के साथ काम करते समय आवश्यक (लेकिन अनुमति) पैरामीटर या RETURNS TABLE (जो OUT . का निहित उपयोग करता है पैरामीटर)।

round() केवल दो पैरामीटर के साथ numeric . के लिए काम करता है प्रकार। count() सबक्वेरी में एक bigint पैदा करता है परिणाम और एक sum() इस पर bigint एक numeric उत्पन्न करता है परिणाम, इस प्रकार हम एक numeric . से निपटते हैं नंबर अपने आप आ जाता है और सब कुछ ठीक हो जाता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मैं Postgres 9.3 में वर्तमान समयक्षेत्र का नाम कैसे प्राप्त करूं?

  2. पासवर्ड के बिना psql कमांड के साथ बैच फ़ाइल चलाएँ

  3. स्प्रिंग बूट एप्लिकेशन हिकारी-पूल-1 पर अटक जाता है - प्रारंभ...

  4. मनमानी उपयोगकर्ता को विचारों पर सभी विशेषाधिकार कैसे प्रदान करें

  5. PostgreSQL के लिए स्लोनी प्रतिकृति के लिए एक विशेषज्ञ की मार्गदर्शिका