2012-07-14 13 views
10

मुझे लगता है कि मैं यहाँ एक कठिन एक है तक को शामिल करें ... :(समूह में गायब महीने क्वेरी

मैं जब महीने के आदेश संख्या प्राप्त करने के लिए कोशिश कर रहा हूँ, यहाँ तक कि शून्य यहाँ समस्या क्वेरी है:।

SELECT datename(month, OrderDate) as Month, COUNT(OrderNumber) AS Orders 
FROM OrderTable 
WHERE OrderDate >= '2012-01-01' and OrderDate <= '2012-06-30' 
GROUP BY year(OrderDate), month(OrderDate), datename(month, OrderDate) 

क्या मैं पाने के लिए देख रहा हूँ कुछ इस तरह है:।

Month   Orders 
-----   ------ 
January   10 
February   7 
March   0 
April   12 
May    0 
June    5 

... लेकिन मेरी क्वेरी मार्च और मई के लिए एक पंक्ति को छोड़ देता है मैं COALESCE(COUNT(OrderNumber), 0) और ISNULL(COUNT(OrderNumber), 0) की कोशिश की है, लेकिन मैं बहुत यकीन है कि समूह सीए है इसका उपयोग करने के लिए नहीं।

+3

ऐसा लगता है कि 'OrderTable' मार्च या मई के लिए कोई रिकॉर्ड है, तो अकेले इस तालिका से चयन उन महीनों के लिए एक परिणाम नहीं लौटा सकता। संभावित कार्य-आस-पास: यदि आपके डेटाबेस में तिथियों की एक मास्टर टेबल है, तो आप इसका लाभ उठा सकते हैं, या आप फ्लाई पर अपनी तिथियों की अपनी तालिका बना सकते हैं। –

+1

@andyholaday की तरह कहा - जनवरी के साथ एक लुकअप टेबल बनाएं ... दिसंबर और बाएं से जुड़ें, और आपको गुम महीनों मिलेंगे। – kd7

उत्तर

21

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

DECLARE @StartDate SMALLDATETIME, @EndDate SMALLDATETIME; 

SELECT @StartDate = '20120101', @EndDate = '20120630'; 

;WITH d(d) AS 
(
    SELECT DATEADD(MONTH, n, DATEADD(MONTH, DATEDIFF(MONTH, 0, @StartDate), 0)) 
    FROM (SELECT TOP (DATEDIFF(MONTH, @StartDate, @EndDate) + 1) 
    n = ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 
    FROM sys.all_objects ORDER BY [object_id]) AS n 
) 
SELECT 
    [Month] = DATENAME(MONTH, d.d), 
    [Year]  = YEAR(d.d), 
    OrderCount = COUNT(o.OrderNumber) 
FROM d LEFT OUTER JOIN dbo.OrderTable AS o 
    ON o.OrderDate >= d.d 
    AND o.OrderDate < DATEADD(MONTH, 1, d.d) 
GROUP BY d.d 
ORDER BY d.d; 
+0

वाह, प्रभावशाली! आपके चयन ने सही क्रम गणना नहीं की है, लेकिन आपके भाग ने बहुत अच्छा काम किया है ... इसलिए मैंने बस अपने चयन के साथ एक सबक्वायरी के रूप में परिणामों को शामिल किया और यह महान, साल और सब कुछ काम करता है! –

+0

आपको बहुत बहुत धन्यवाद, यह वही है जो मुझे कोड का एक बड़ा टुकड़ा चाहिए। – Enzero

+0

यह क्वेरी LINQ में कैसे दिखती है? यह वास्तव में मेरे लिए एक दुःस्वप्न है T_T – Baby

1

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

;With Months (Month) 
AS 
(

    select 'January' as Month 
    UNION 
    select 'February' as Month 
    UNION 
    select 'March' as Month 
    UNION 
    select 'April' as Month 
    UNION 
    select 'May' as Month 
    UNION 
    select 'June' as Month 
    UNION 
    select 'July' as Month 
    UNION 
    select 'August' as Month 
    UNION 
    select 'September' as Month 
    UNION 
    select 'October' as Month 
    UNION 
    select 'November' as Month 
    UNION 
    select 'December' as Month 

) 
--Also you could have them in a "Months" Table 
अपनी मेज के साथ

तो बस JOIN इस तालिका:

Select 
    SELECT datename(month, OrderDate) as Month, COUNT(OrderNumber) 
    FROM Months T1 
    LEFT JOIN OrderTable T2 on datename(month, T2.OrderDate) = T2.Month 
    WHERE (T2.OrderDate >= '2012-01-01' and T2.OrderDate <= '2012-06-30') 
OR T2.OrderDate IS NULL --So will show you the months with no rows 
    GROUP BY year(T2.OrderDate), month(T2.OrderDate), datename(month, T2.OrderDate) 

यह काम करता है आशा है!

+0

आपके प्रयास के लिए धन्यवाद, लेकिन यह मेरे लिए काम नहीं किया। मैं सोच रहा था कि टी 1 और टी 2 चारों ओर स्विच किए गए थे, लेकिन मुझे यह नहीं मिला। मैं नहीं देखता कि यह वैसे भी कैसे काम कर सकता है क्योंकि ऑर्डरटेबल से महीनों की तालिका में शामिल होने के लिए अभी भी कोई परिणाम नहीं हैं। अगर मैं अवधारणा को समझता हूं, तो सबसे अच्छा मुझे सभी 12 महीने मिलेंगे, जो मैं नहीं ढूंढ रहा हूं। –

1

यहाँ एक पुनरावर्ती CTE उपयोग कर रहा है:

declare @StartDate datetime = '2015-04-01'; 
declare @EndDate datetime = '2015-06-01'; 

-- sample data 
declare @orders table (OrderNumber int, OrderDate datetime); 
insert into @orders 
select 11, '2015-04-02' 
union all 
select 12, '2015-04-03' 
union all 
select 13, '2015-05-03' 
; 

-- recursive CTE 
with dates 
as (
    select @StartDate as reportMonth 
    union all 
    select dateadd(m, 1, reportMonth) 
    from dates 
    where reportMonth < @EndDate 
    ) 
select 
    reportMonth, 
    Count = count(o.OrderNumber) 
from dates 
left outer join @orders as o 
    on o.OrderDate >= reportMonth 
    and o.OrderDate < dateadd(MONTH, 1, reportMonth) 
group by 
    reportMonth 
option (maxrecursion 0); 
; 
संबंधित मुद्दे