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

एक गतिशील क्रॉसस्टैब क्वेरी निष्पादित करें

आप जो मांगते हैं वह असंभव है . SQL एक कड़ाई से टाइप की जाने वाली भाषा है। PostgreSQL फ़ंक्शंस को रिटर्न प्रकार घोषित करने की आवश्यकता है (RETURNS .. ) निर्माण के समय . पर

इसके चारों ओर एक सीमित तरीका बहुरूपी कार्यों के साथ है। यदि आप कार्य के समय कॉल . पर वापसी प्रकार प्रदान कर सकते हैं . लेकिन यह आपके प्रश्न से स्पष्ट नहीं है।

  • एक PL/pgSQL फ़ंक्शन को रिफ़ैक्टर करें ताकि विभिन्न SELECT क्वेरीज़ का आउटपुट लौटाया जा सके

आप कर सकते हैं अनाम रिकॉर्ड के साथ पूरी तरह से गतिशील परिणाम लौटाएं। लेकिन फिर आपको प्रत्येक कॉल के साथ कॉलम परिभाषा सूची प्रदान करने की आवश्यकता होती है। और आप लौटे कॉलम के बारे में कैसे जानते हैं? कैच 22.

आपको जिस चीज की जरूरत है या उसके साथ काम कर सकते हैं, उसके आधार पर विभिन्न वर्कअराउंड हैं। चूंकि आपके सभी डेटा कॉलम समान डेटा प्रकार साझा करते हैं, इसलिए मेरा सुझाव है कि एक सरणी . लौटाएं :text[] . या आप hstore . जैसे दस्तावेज़ प्रकार वापस कर सकते हैं या json . संबंधित:

  • CASE और GROUP BY के साथ पिवट करने का डायनामिक विकल्प

  • अज्ञात कुंजियों के सेट के लिए hstore कुंजियों को स्तंभों में गतिशील रूप से रूपांतरित करें

लेकिन केवल दो कॉलों का उपयोग करना आसान हो सकता है:1:पोस्टग्रेज़ को क्वेरी बनाने दें। 2:लौटाई गई पंक्तियों को निष्पादित और पुनर्प्राप्त करें।

  • एकल SQL कथन का उपयोग करके अनेक अधिकतम () मानों का चयन करना

जैसा कि आपके प्रश्न बिल्कुल . में प्रस्तुत किया गया है, मैं एरिक मिनिकेल के फ़ंक्शन का उपयोग नहीं करूंगा . यह दुर्भावनापूर्ण रूप से विकृत पहचानकर्ताओं के माध्यम से SQL इंजेक्शन के विरुद्ध सुरक्षित नहीं है। format() का प्रयोग करें क्वेरी स्ट्रिंग बनाने के लिए जब तक कि आप पोस्टग्रेज़ 9.1 से पुराना पुराना संस्करण नहीं चला रहे हों।

एक छोटा और साफ-सुथरा कार्यान्वयन इस तरह दिख सकता है:

CREATE OR REPLACE FUNCTION xtab(_tbl regclass, _row text, _cat text
                              , _expr text  -- still vulnerable to SQL injection!
                              , _type regtype)
  RETURNS text AS
$func$
DECLARE
   _cat_list text;
   _col_list text;
BEGIN

-- generate categories for xtab param and col definition list    
EXECUTE format(
 $$SELECT string_agg(quote_literal(x.cat), '), (')
        , string_agg(quote_ident  (x.cat), %L)
   FROM  (SELECT DISTINCT %I AS cat FROM %s ORDER BY 1) x$$
 , ' ' || _type || ', ', _cat, _tbl)
INTO  _cat_list, _col_list;

-- generate query string
RETURN format(
'SELECT * FROM crosstab(
   $q$SELECT %I, %I, %s
      FROM   %I
      GROUP  BY 1, 2  -- only works if the 3rd column is an aggregate expression
      ORDER  BY 1, 2$q$
 , $c$VALUES (%5$s)$c$
   ) ct(%1$I text, %6$s %7$s)'
, _row, _cat, _expr  -- expr must be an aggregate expression!
, _tbl, _cat_list, _col_list, _type
);

END
$func$ LANGUAGE plpgsql;

आपके मूल संस्करण के समान फ़ंक्शन कॉल। फ़ंक्शन crosstab() अतिरिक्त मॉड्यूल tablefunc . द्वारा प्रदान किया जाता है जिसे स्थापित किया जाना है। मूल बातें:

  • PostgreSQL क्रॉसस्टैब क्वेरी

यह कॉलम और टेबल नामों को सुरक्षित रूप से संभालता है। वस्तु पहचानकर्ता प्रकारों के उपयोग पर ध्यान दें regclass और regtype . स्कीमा-योग्य नामों के लिए भी काम करता है।

  • तालिका नाम PostgreSQL फ़ंक्शन पैरामीटर के रूप में

हालांकि, यह पूरी तरह से सुरक्षित नहीं है जब आप अभिव्यक्ति के रूप में निष्पादित करने के लिए एक स्ट्रिंग पास करते हैं (_expr - cellc आपकी मूल क्वेरी में)। इस तरह का इनपुट एसक्यूएल इंजेक्शन के खिलाफ स्वाभाविक रूप से असुरक्षित है और इसे आम जनता के सामने कभी नहीं दिखाया जाना चाहिए।

  • पोस्टग्रेज फ़ंक्शन बनाम तैयार क्वेरी में SQL इंजेक्शन

तालिका को केवल एक बार स्कैन करता है दोनों श्रेणियों की सूचियों के लिए और थोड़ा तेज़ होना चाहिए।

अभी भी पूरी तरह से गतिशील पंक्ति प्रकारों को वापस नहीं कर सकता क्योंकि यह सख्ती से संभव नहीं है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL इंडेक्स बनाएं

  2. PostgreSQL प्रतिकृति 101 के लिए विफलता

  3. Postgresql द्वारा उत्पन्न अनुक्रम से पहले एक स्ट्रिंग को उपसर्ग कैसे करें?

  4. रेल/पोस्टग्रेस्क्ल एसक्यूएल मतभेद डब्ल्यू/तिथियां

  5. NULL या IS NULL के साथ क्लॉज में