एक ही टेबल पर विभिन्न कॉलमों की गिनती कैसे करें


15

तालिका # 01 Status:

StatusID    Status
-----------------------
 1          Opened
 2          Closed
 3          ReOpened
 4          Pending

तालिका # 02 Claims:

ClaimID     CompanyName StatusID
--------------------------------------
1               ABC     1
2               ABC     1
3               ABC     2
4               ABC     4
5               XYZ     1
6               XYZ     1

अपेक्षित परिणाम:

CompanyName TotalOpenClaims TotalClosedClaims TotalReOpenedClaims TotalPendingClaims
--------------------------------------------------------------------------------
ABC                 2           1                      0               1
XYZ                 2           0                      0               0

मुझे क्वेरी लिखने की आवश्यकता कैसे है ताकि मुझे उम्मीद के मुताबिक परिणाम मिल सके?

जवाबों:


27

यह सबसे आसान SUM()और एक CASEकथन है:

select CompanyName, 
sum(case when StatusID=1 then 1 else 0 end) as TotalOpenClaims,
sum(case when StatusID=2 then 1 else 0 end) as TotalClosedClaims,
sum(case when StatusID=3 then 1 else 0 end) as TotalReOpenedClaims,
sum(case when StatusID=4 then 1 else 0 end) as TotalPendingClaims
from Claims
group by CompanyName;

16

यह एक विशिष्ट धुरी परिवर्तन है, और सशर्त एकत्रीकरण, जैसा कि फिल द्वारा सुझाया गया है , इसे लागू करने का अच्छा पुराना तरीका है।

समान परिणाम प्राप्त करने का एक और अधिक आधुनिक वाक्यविन्यास भी है, जो PIVOT खंड का उपयोग करता है:

SELECT
  CompanyName,
  TotalOpenClaims     = [1],
  TotalClosedClaims   = [2],
  TotalReOpenedClaims = [3],
  TotalPendingClaims  = [4]
FROM
  dbo.Claims
  PIVOT
  (
    COUNT(ClaimID)
    FOR StatusID IN ([1], [2], [3], [4])
  ) AS p
;

आंतरिक रूप से यह निश्चित रूप से सरल वाक्यविन्यास देख फिल के ग्रुप बाय क्वेरी के बराबर है। अधिक सटीक रूप से, यह इस भिन्नता के बराबर है:

SELECT
  CompanyName,
  TotalOpenClaims     = COUNT(CASE WHEN StatusID = 1 THEN ClaimID END),
  TotalClosedClaims   = COUNT(CASE WHEN StatusID = 2 THEN ClaimID END),
  TotalReOpenedClaims = COUNT(CASE WHEN StatusID = 3 THEN ClaimID END),
  TotalPendingClaims  = COUNT(CASE WHEN StatusID = 4 THEN ClaimID END)
FROM
  dbo.Claims
GROUP BY
  CompanyName
;

तो, एक PIVOT क्वेरी अनिवार्य रूप से एक अंतर्निहित ग्रुप BY क्वेरी है।

हालांकि, PIVOT क्वेरी सशर्त एकत्रीकरण के साथ स्पष्ट BY BY प्रश्नों से निपटने में कुख्यात हैं। जब आप PIVOT का उपयोग कर रहे हैं, तो आपको हमेशा इस एक बात को ध्यान में रखना होगा:

  • डेटासेट के सभी कॉलम ( Claimsइस मामले में) जिन्हें PIVOT क्लॉज में स्पष्ट रूप से उल्लेखित नहीं किया गया है, वे GROUP BY कॉलम हैं

यदि Claimsआपके उदाहरण में दिखाए गए केवल तीन कॉलम शामिल हैं, तो ऊपर दी गई PIVOT क्वेरी अपेक्षा के अनुरूप काम करेगी, क्योंकि जाहिरा तौर पर CompanyNamePIVOT में स्पष्ट रूप से उल्लेखित एकमात्र कॉलम नहीं है और इस प्रकार निहित समूह BY की एकमात्र कसौटी के रूप में समाप्त होता है।

हालाँकि, यदि Claimsअन्य कॉलम (कहते हैं ClaimDate) हैं, तो वे अंतर्निहित रूप से अतिरिक्त GROUP BY कॉलम के रूप में उपयोग किए जाएंगे - यानी, आपकी क्वेरी अनिवार्य रूप से कर रही है

GROUP BY CompanyName, ClaimDate, ... /* whatever other columns there are*/`

परिणाम सबसे अधिक संभावना है कि आप क्या चाहते हैं नहीं होगा।

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

SELECT
  CompanyName,
  TotalOpenClaims     = [1],
  TotalClosedClaims   = [2],
  TotalReOpenedClaims = [3],
  TotalPendingClaims  = [4]
FROM
  (SELECT ClaimID, CompanyName, StatusID FROM dbo.Claims) AS derived
  PIVOT
  (
    COUNT(ClaimID)
    FOR StatusID IN ([1], [2], [3], [4])
  ) AS p
;

फिर भी, यदि Claimsपहले से ही एक व्युत्पन्न तालिका है, तो घोंसले के एक और स्तर को जोड़ने की कोई आवश्यकता नहीं है, बस यह सुनिश्चित करें कि वर्तमान व्युत्पन्न तालिका में आप केवल उत्पादन करने के लिए आवश्यक कॉलम का चयन कर रहे हैं।

आप मैनुअल में PIVOT के बारे में अधिक पढ़ सकते हैं:


1

माना जाता है कि मेरा अनुभव ज्यादातर MySQL के साथ है और मैंने SQL सर्वर पर ज्यादा समय नहीं बिताया है। अगर निम्नलिखित क्वेरी काम नहीं करती तो मुझे बहुत आश्चर्य होगा:

SELECT 
  CompanyName, 
  status, 
  COUNT(status) AS 'Total Claims' 
FROM Claim AS c 
  JOIN Status AS s ON c.statusId = s.statusId 
GROUP BY 
  CompanyName, 
  status;

यह आपको उस प्रारूप में आउटपुट नहीं देता है जो आप चाहते हैं, लेकिन यह आपको वह सभी जानकारी देता है जो आप चाहते हैं, भले ही आप शून्य मामलों को छोड़ दें। यह मेरे लिए एक प्रश्न के अंदर CASE कथनों से निपटने की तुलना में बहुत सरल लगता है जो एक विशेष रूप से बुरे विचार की तरह महसूस करते हैं यदि इसे केवल स्वरूपण के लिए उपयोग किया जा रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.