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

एक साथ कई कॉलम को प्रभावित करने के लिए PostgreSQL में CASE का उपयोग करना

<एच3>1. मानक-एसक्यूएल:LEFT JOIN मानों की एक पंक्ति

आप LEFT JOIN कर सकते हैं शर्त का उपयोग करके मूल्यों की एक पंक्ति (जिससे एक बार इसका मूल्यांकन किया जाता है)। फिर आप के साथ प्रति कॉलम फ़ॉलबैक मान जोड़ सकते हैं COALESCE()

यह सिंटैक्स संस्करण छोटा और थोड़ा तेज़ है जिसमें कई मान हैं - विशेष रूप से एक महंगी / लंबी स्थिति के लिए दिलचस्प:

SELECT COALESCE(x.txt1, trim(r2.team_name))     AS testing_testing
     , COALESCE(x.txt2, trim(r2.normal_data))   AS test_response
     , COALESCE(x.txt3, trim(r2.normal_data_2)) AS another_example
FROM   rtp
JOIN   rtd2 r2 ON <unknown condition> -- missing context in question
LEFT   JOIN (
   SELECT 'testing'::text         AS txt1
        , 'test example'::text    AS txt2
        , 'test example #2'::text AS txt3
   ) x ON rtp.team_id = rtp.sub_team_id;

चूंकि व्युत्पन्न तालिका x एक एकल . से मिलकर बनता है पंक्ति, बिना किसी शर्त के जुड़ना ठीक है।

स्पष्ट प्रकार कास्ट सबक्वेरी में आवश्यक हैं। मैं text का उपयोग करता हूं उदाहरण में (जो वैसे भी स्ट्रिंग अक्षर के लिए डिफ़ॉल्ट है)। अपने वास्तविक डेटा प्रकारों का उपयोग करें। सिंटैक्स शॉर्टकट value::type पोस्टग्रेज-विशिष्ट है, cast(value AS type) का उपयोग करें मानक SQL के लिए।

अगर शर्त TRUE नहीं है , x . में सभी मान NULL हैं, और COALESCE शुरू होता है।

या , चूंकि सभी उम्मीदवार मान तालिका rtd2 . से आते हैं आपके विशेष मामले में, LEFT JOIN करने के लिए rtd2 मूल CASE . का उपयोग करना शर्त और CROSS JOIN डिफ़ॉल्ट मानों वाली एक पंक्ति में:

SELECT COALESCE(trim(r2.team_name),     x.txt1) AS testing_testing
     , COALESCE(trim(r2.normal_data),   x.txt2) AS test_response
     , COALESCE(trim(r2.normal_data_2), x.txt3) AS another_example
FROM   rtp
LEFT   JOIN rtd2 r2 ON <unknown condition>  -- missing context in question
                   AND rtp.team_id = rtp.sub_team_id
CROSS  JOIN (
   SELECT 'testing'::text         AS txt1
        , 'test example'::text    AS txt2
        , 'test example #2'::text AS txt3
   ) x;

यह शामिल होने की स्थिति और बाकी क्वेरी पर निर्भर करता है।

<एच3>2. PostgreSQL-विशिष्ट

2a. एक सरणी का विस्तार करें

यदि आपके विभिन्न कॉलम समान डेटा प्रकार साझा करते हैं , आप एक सबक्वेरी में एक सरणी का उपयोग कर सकते हैं और इसे बाहरी SELECT . में विस्तारित कर सकते हैं :

SELECT x.combo[1], x.combo[2], x.combo[3]
FROM  (
   SELECT CASE WHEN rtp.team_id = rtp.sub_team_id
            THEN '{test1,test2,test3}'::text[]
            ELSE ARRAY[trim(r2.team_name)
                     , trim(r2.normal_data)
                     , trim(r2.normal_data_2)]
          END AS combo
   FROM   rtp
   JOIN   rtd2 r2 ON <unknown condition>
   ) x;

यदि कॉलम समान डेटा प्रकार साझा नहीं करते हैं तो यह और अधिक जटिल हो जाता है। आप या तो उन सभी को text . में डाल सकते हैं (और वैकल्पिक रूप से बाहरी SELECT . में वापस कनवर्ट करें ), या आप कर सकते हैं ...

<एच4>2बी. एक पंक्ति प्रकार को विघटित करें

आप विभिन्न प्रकार के मूल्यों को रखने के लिए एक कस्टम समग्र प्रकार (पंक्ति प्रकार) का उपयोग कर सकते हैं और बस इसे बाहरी SELECT में विस्तारित कर सकते हैं . मान लें कि हमारे पास तीन कॉलम हैं:text , integer और date . दोहराए गए . के लिए उपयोग करें, एक कस्टम मिश्रित प्रकार बनाएं:

CREATE TYPE my_type (t1 text, t2 int, t3 date);

या यदि मौजूदा तालिका का प्रकार मेल खाता है, तो आप तालिका के नाम को समग्र प्रकार के रूप में उपयोग कर सकते हैं।

या यदि आपको केवल अस्थायी रूप से . प्रकार की आवश्यकता है , आप एक TEMPORARY TABLE . बना सकते हैं , जो आपके सत्र . की अवधि के लिए एक अस्थायी प्रकार दर्ज करता है :

CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date);

आप इसे एकल लेन-देन . के लिए भी कर सकते हैं :

CREATE TEMP TABLE my_type (t1 text, t2 int, t3 date) ON COMMIT DROP;

तब आप इस क्वेरी का उपयोग कर सकते हैं:

SELECT (x.combo).*  -- parenthesis required
FROM  (
   SELECT CASE WHEN rtp.team_id = rtp.sub_team_id
             THEN ('test', 3, now()::date)::my_type  -- example values
             ELSE (r2.team_name
                 , r2.int_col
                 , r2.date_col)::my_type
          END AS combo
   FROM   rtp
   JOIN   rtd2 r2 ON <unknown condition>
   ) x;

या यहां तक ​​कि बस (ऊपर जैसा ही, सरल, छोटा, समझने में शायद कम आसान):

SELECT (CASE WHEN rtp.team_id = rtp.sub_team_id
           THEN ('test', 3, now()::date)::my_type
           ELSE (r2.team_name, r2.int_col, r2.date_col)::my_type
        END).*
FROM   rtp
JOIN   rtd2 r2 ON <unknown condition>;

CASE इस तरह प्रत्येक कॉलम के लिए अभिव्यक्ति का मूल्यांकन एक बार किया जाता है। यदि मूल्यांकन तुच्छ नहीं है, तो सबक्वेरी वाला दूसरा संस्करण तेज होगा।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एक ही तालिका से दो प्रश्नों को घटाएं

  2. PHP ssh2_tunnel का उपयोग करके PostgreSQL से कनेक्ट करें

  3. Django - संबंध संबंध मौजूद नहीं है। python manage.py माइग्रेट नहीं चला सकता?

  4. org.postgresql.util.PSQLException:FATAL:क्षमा करें, पहले से ही बहुत सारे ग्राहक हैं

  5. RHEL 6.5 libpq-fe.h त्रुटि पर RPostgreSQL स्थापित करें