2013-07-23 12 views
11

के लिए एसयूएम (केस जब x THEN 1 ELSE 0) नीचे देखे गए प्रश्न के लिए बेहतर दृष्टिकोण है या नहीं। मैं जो करने की कोशिश कर रहा हूं वह सारांश रिपोर्ट बना रहा है, जो आंकड़ों को संकलित करता है।एसक्यूएल क्वेरी - एकाधिक कॉलम

SELECT CAST(Detail.ReceiptDate AS DATE) AS 'DATE' 
, SUM(CASE WHEN Detail.Type = 'TotalMailed' THEN 1 ELSE 0 END) AS 'TOTALMAILED' 
, SUM(CASE WHEN Detail.Type = 'TotalReturnMail' THEN 1 ELSE 0 END) AS 'TOTALUNDELINOTICESRECEIVED' 
, SUM(CASE WHEN Detail.Type = 'TraceReturnedMail' THEN 1 ELSE 0 END) AS 'TRACEUNDELNOTICESRECEIVED' 
FROM 
(
select SentDate AS 'ReceiptDate', 'TotalMailed' AS 'Type' 
from MailDataExtract 
where sentdate is not null 
UNION ALL 
select MDE.ReturnMailDate AS 'ReceiptDate', 'TotalReturnMail' AS 'Type' 
from MailDataExtract MDE 
where MDE.ReturnMailDate is not null 
UNION ALL 
select MDE.ReturnMailDate AS 'ReceiptDate', 'TraceReturnedMail' AS 'Type' 
from MailDataExtract MDE 
    inner join DTSharedData.dbo.ScanData SD ON SD.ScanDataID = MDE.ReturnScanDataID 
where MDE.ReturnMailDate is not null AND SD.ReturnMailTypeID = 1 
) AS Detail 
GROUP BY CAST(Detail.ReceiptDate AS DATE) 
ORDER BY 1 

यह केवल क्वेरी (जो एक रिपोर्ट में प्रयोग किया जाता है) का एक नमूना के रूप में वहाँ अन्य स्तंभों के एक नंबर और अन्य आंकड़े के लिए तर्क कर रहे हैं जिस तरह से अधिक जटिल है। इस तरह की रिपोर्ट/इस तरह की रिपोर्ट लिखने के लिए कोई और शानदार तरीका है?

+0

एक proc या एक दृश्य, या कुछ और इस है? असल में, क्या आप चर प्रस्तुत कर सकते हैं और एकाधिक कथन चला सकते हैं, या यह सिर्फ एक बड़ा 'चयन' कथन है? –

+0

यह एक proc है जिसका उपयोग एसएसआरएस रिपोर्ट के लिए किया जाएगा, इसलिए इसे अनिवार्य रूप से एक चुनिंदा कथन होना होगा क्योंकि मुझे परिणाम सेट (दाएं?) – MickJuice

+0

हाँ वापस करने की आवश्यकता है, अंततः आपके पास एक बड़ा 'चयन' होगा अंत में, लेकिन चूंकि यह एक प्रो में है, इसलिए आपके पास अपनी क्वेरी को छोटे, सरल हिस्सों में विभाजित करने की क्षमता होगी, साथ ही साथ वैरिएबल को वैल्यू असाइन करना होगा। यह पठनीयता में एक बड़ा अंतर कर सकता है। उदाहरण के लिए, इन तीन उप-श्रेणियों को 'संघ' या समूहबद्ध करने के बजाय, आपके पास तीन छोटे स्टैंडअलोन प्रश्न अग्रिम में चल सकते हैं जो चर के परिणामों को सारांशित करते हैं, फिर बस अपनी वापसी क्वेरी के लिए उन चर का चयन करें। संभावित रूप से पढ़ने और समझने के लिए बहुत आसान है, और संभवतः बेहतर प्रदर्शन भी। –

उत्तर

8

मैं निम्न तरीकों से क्वेरी बदल जाएगा:

  1. सबक्वेरी में एकत्रीकरण करो। यह group by को अनुकूलित करने के लिए तालिका के बारे में अधिक जानकारी का लाभ उठा सकता है।
  2. दूसरी और तीसरी उपक्वियों को मिलाएं। वे एक ही कॉलम पर एकत्रित हो रहे हैं। यह सुनिश्चित करने के लिए कि सभी डेटा उपलब्ध है, left outer join का उपयोग करने की आवश्यकता है।
  3. count(<fieldname>) का उपयोग करके आप is null पर तुलना को खत्म कर सकते हैं। यह दूसरे और तीसरे गणना मूल्यों के लिए महत्वपूर्ण है।
  4. दूसरे और तीसरे प्रश्नों को गठबंधन करने के लिए, इसे mde तालिका से एक आईडी गिनने की आवश्यकता है। ये mde.mdeid का उपयोग करते हैं।

निम्न संस्करण union all का उपयोग करके अपने उदाहरण इस प्रकार है:

SELECT CAST(Detail.ReceiptDate AS DATE) AS "Date", 
     SUM(TOTALMAILED) as TotalMailed, 
     SUM(TOTALUNDELINOTICESRECEIVED) as TOTALUNDELINOTICESRECEIVED, 
     SUM(TRACEUNDELNOTICESRECEIVED) as TRACEUNDELNOTICESRECEIVED 
FROM ((select SentDate AS "ReceiptDate", COUNT(*) as TotalMailed, 
       NULL as TOTALUNDELINOTICESRECEIVED, NULL as TRACEUNDELNOTICESRECEIVED 
     from MailDataExtract 
     where SentDate is not null 
     group by SentDate 
    ) union all 
     (select MDE.ReturnMailDate AS ReceiptDate, 0, 
       COUNT(distinct mde.mdeid) as TOTALUNDELINOTICESRECEIVED, 
       SUM(case when sd.ReturnMailTypeId = 1 then 1 else 0 end) as TRACEUNDELNOTICESRECEIVED 
     from MailDataExtract MDE left outer join 
      DTSharedData.dbo.ScanData SD 
      ON SD.ScanDataID = MDE.ReturnScanDataID 
     group by MDE.ReturnMailDate; 
    ) 
    ) detail 
GROUP BY CAST(Detail.ReceiptDate AS DATE) 
ORDER BY 1; 

निम्नलिखित कुछ इसी तरह full outer join का उपयोग करता है:

SELECT coalesce(sd.ReceiptDate, mde.ReceiptDate) AS "Date", 
     sd.TotalMailed, mde.TOTALUNDELINOTICESRECEIVED, 
     mde.TRACEUNDELNOTICESRECEIVED 
FROM (select cast(SentDate as date) AS "ReceiptDate", COUNT(*) as TotalMailed 
     from MailDataExtract 
     where SentDate is not null 
     group by cast(SentDate as date) 
    ) sd full outer join 
    (select cast(MDE.ReturnMailDate as date) AS ReceiptDate, 
      COUNT(distinct mde.mdeID) as TOTALUNDELINOTICESRECEIVED, 
      SUM(case when sd.ReturnMailTypeId = 1 then 1 else 0 end) as TRACEUNDELNOTICESRECEIVED 
    from MailDataExtract MDE left outer join 
      DTSharedData.dbo.ScanData SD 
      ON SD.ScanDataID = MDE.ReturnScanDataID 
    group by cast(MDE.ReturnMailDate as date) 
    ) mde 
    on sd.ReceiptDate = mde.ReceiptDate 
ORDER BY 1; 
0

मुझे लगता है कि आपको समूह करने के लिए एक सबक्वायरी बनाना चाहिए। इस मामले में आंतरिक सबक्वायरी कुछ पंक्तियां देता है और आपको CASE कथन की आवश्यकता नहीं होती है। तो मुझे लगता है यह तेजी से होने जा रहा है:

select Detail.ReceiptDate AS 'DATE', 
     SUM(TotalMailed), 
     SUM(TotalReturnMail), 
     SUM(TraceReturnedMail) 

from 
(

select SentDate AS 'ReceiptDate', 
     count('TotalMailed') AS TotalMailed, 
     0 as TotalReturnMail, 
     0 as TraceReturnedMail 
from MailDataExtract 
where sentdate is not null 
GROUP BY SentDate 

UNION ALL 
select MDE.ReturnMailDate AS 'ReceiptDate', 
     0 AS TotalMailed, 
     count(TotalReturnMail) as TotalReturnMail, 
     0 as TraceReturnedMail 
from MailDataExtract MDE 
where MDE.ReturnMailDate is not null 
GROUP BY MDE.ReturnMailDate 

UNION ALL 

select MDE.ReturnMailDate AS 'ReceiptDate', 
     0 AS TotalMailed, 
     0 as TotalReturnMail, 
     count(TraceReturnedMail) as TraceReturnedMail 

from MailDataExtract MDE 
    inner join DTSharedData.dbo.ScanData SD 
     ON SD.ScanDataID = MDE.ReturnScanDataID 
    where MDE.ReturnMailDate is not null AND SD.ReturnMailTypeID = 1 
GROUP BY MDE.ReturnMailDate 

) as Detail 
GROUP BY Detail.ReceiptDate 
ORDER BY 1 
संबंधित मुद्दे