2012-07-14 16 views
10

Ben burada zorlu bir tane var By Group eksik ay dahil sıfır Problem sorgusuysa.zaman bile, aylık bir sipariş sayısı elde çalışıyorum</p> <p>:(... sorguda

Ben almak için arıyorum ne
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) 

böyle bir şeydir.

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

... ama benim sorgu Mart ve Mayıs için bir satır atlar ben COALESCE(COUNT(OrderNumber), 0) ve ISNULL(COUNT(OrderNumber), 0) denedim ama eminim gruplama ca bunu kullanmamak için kullanıyor.

+3

O kadar olanlar aylarca bir sonuç döndüremez yalnız bu tablodan seçerek görünüyor. Olası iş çevreleri: Veritabanınız bir ana tablo tablosuna sahipse, bunu kaldırabilirsin ya da kendi tarihler tablosunu anında yaratabilirsiniz. –

+1

Beğen @andyholaday dedi - Ocak ile bir arama tablosu oluşturun ... Aralık ve bir Sol birleştirme yapın ve eksik ayları alacaksınız. – kd7

cevap

21

Bu çözüm, istediğiniz ay listesini kodlamanızı gerektirmez, yapmanız gereken tek şey başlangıç ​​tarihi ve herhangi bir bitiş tarihi sağlamaktır ve sizin için ay sınırlarını hesaplar. Yılda 12 aydan fazla süreyi destekleyecek ve böylece başlangıç ​​ve bitiş tarihlerinizin bir yıl sınırını geçebileceği ve doğru şekilde sipariş verebileceği ve doğru ayın ve yıllarını gösterebileceği şekilde yıl içinde çıktılar. İşte

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

Vay, etkileyici! SELECT'iniz doğru sipariş sayısını vermedi, ancak İKİNCİ bölümünüz harika çalıştı ... Bu yüzden sadece İKİNCİ'nin sonuçlarını bir alt sorgu olarak SEÇİMİNE KATILIYORUM ve harika, yıl ve hep birlikte çalışıyor! –

+0

Teşekkür ederim, bu çok büyük bir kod parçasına ihtiyacım vardı. – Enzero

+0

Bu sorgu nasıl LINQ içinde görünüyor? Bu benim için gerçekten bir kabus T_T – Baby

1

Sorgunuzdan beri Sadece İstediğiniz ayı tahmin edemediğiniz bir yerde saklamak istediğiniz Ayları sahip olmanız gerekecek, Tabloya katıl ve sonra gruplandır. tablonuzla

;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 
Sonra

Sadece JOIN bu tablo: şey gibi

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) 

çalıştığını umuyoruz!

+0

Çabanız için teşekkürler, ama bu benim için işe yaramadı. T1 ve T2'nin değiştiğini düşünüyordum ama anlayamadım. Nasıl olsa işe yaradığını göremiyorum, çünkü yine de OrderTable'dan aylar tablosuna katılmak için sonuç yok. Kavramı anlarım, en iyisi 12 ay alabiliyordum, bu da benim aradığım şey değil. –

1

özyinelemeli CTE kullanarak biridir: `OrderTable` Mart veya Mayıs için kayıt yok gibi

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); 
; 
İlgili konular