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

ग्रुप बाय + केस स्टेटमेंट

आपकी क्वेरी पहले से ही काम करेगी - सिवाय इसके कि आप नामकरण विरोधों में चल रहे हैं या केवल आउटपुट कॉलम को भ्रमित कर रहे हैं (CASE एक्सप्रेशन) स्रोत कॉलम . के साथ result , जिसमें अलग सामग्री है।

...
GROUP BY model.name, attempt.type, attempt.result
...

आपको GROUP BY करना होगा आपका CASE आपके स्रोत कॉलम के बजाय एक्सप्रेशन:

...
GROUP BY model.name, attempt.type
       , CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END
...

या एक कॉलम उपनाम . प्रदान करें यह FROM . में किसी भी कॉलम नाम से अलग है सूची - या फिर उस कॉलम को प्राथमिकता दी जाती है:

SELECT ...
     , CASE WHEN attempt.result = 0 THEN 0 ELSE 1 END AS result1
...
GROUP BY model.name, attempt.type, result1
...

इस संबंध में SQL मानक बल्कि अजीब है। यहां मैनुअल का हवाला देते हुए:

<ब्लॉकक्वॉट>

ORDER BY में कॉलम के मान को संदर्भित करने के लिए आउटपुट कॉलम के नाम का उपयोग किया जा सकता है और GROUP BY खंड, लेकिन WHERE . में नहीं या HAVING खंड; वहां आपको इसके बजाय व्यंजक लिखना होगा।

और:

<ब्लॉकक्वॉट>

यदि कोई ORDER BY अभिव्यक्ति एक साधारण नाम है जो आउटपुट कॉलम नाम और इनपुट कॉलम नाम दोनों से मेल खाता है, ORDER BY आउटपुट कॉलम नाम के रूप में इसकी व्याख्या करेगा। यह विकल्प के विपरीत है कि GROUP BY कर देगा उसी स्थिति में। इस असंगति को SQL मानक के साथ संगत करने के लिए बनाया गया है।

बोल्ड मेरा जोर।

स्थितीय संदर्भ . का उपयोग करके इन विरोधों से बचा जा सकता है (क्रमिक संख्या) GROUP BY . में और ORDER BY , SELECT . में आइटम का संदर्भ देना बाएं से दाएं सूची। समाधान नीचे देखें।
समस्या यह है कि इसे पढ़ना कठिन हो सकता है और SELECT में संपादन के लिए असुरक्षित हो सकता है सूची (कोई तदनुसार स्थितीय संदर्भों को अनुकूलित करना भूल सकता है)।

लेकिन आप नहीं करते हैं कॉलम जोड़ना होगा day GROUP BY . के लिए खंड, जब तक यह एक स्थिर मान रखता है (CURRENT_DATE-1 )।

उचित जॉइन सिंटैक्स और स्थितीय संदर्भों के साथ पुनर्लेखित और सरलीकृत यह इस तरह दिख सकता है:

SELECT m.name
     , a.type
     , CASE WHEN a.result = 0 THEN 0 ELSE 1 END AS result
     , CURRENT_DATE - 1 AS day
     , count(*) AS ct
FROM   attempt    a
JOIN   prod_hw_id p USING (hard_id)
JOIN   model      m USING (model_id)
WHERE  ts >= '2013-11-06 00:00:00'  
AND    ts <  '2013-11-07 00:00:00'
GROUP  BY 1,2,3
ORDER  BY 1,2,3;

यह भी ध्यान दें कि मैं कॉलम नाम time . से बच रहा हूं . यह एक आरक्षित शब्द है और इसे कभी भी पहचानकर्ता के रूप में उपयोग नहीं किया जाना चाहिए। इसके अलावा, आपका "समय" स्पष्ट रूप से एक timestamp है या date , इसलिए यह भ्रामक है।



  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. प्राथमिक कुंजी तालिका में डुप्लिकेट पंक्तियाँ।

  3. PostgreSQL डेटाबेस से छवि प्रदर्शित करना, bytea

  4. हाइबरनेट के साथ मानचित्रण सरणी

  5. उपनाम द्वारा आदेश काम नहीं कर रहा