簡體   English   中英

SQL組和按月求和-默認為零

[英]SQL Group and Sum By Month - Default to Zero

我目前正在按月對庫存使用情況進行分組和匯總:

SELECT      Inventory.itemid AS ItemID,
            SUM(Inventory.Totalunits) AS Individual_MonthQty,
            MONTH(Inventory.dadded) AS Individual_MonthAsNumber,
            DATENAME(MONTH, Inventory.dadded) AS Individual_MonthAsString
FROM        Inventory
WHERE       Inventory.invtype = 'Shipment'
AND         Inventory.dadded >= @StartRange
AND         Inventory.dadded <= @EndRange
GROUP BY    Inventory.ItemID, 
            MONTH(Inventory.dadded), 
            DATENAME(MONTH, Inventory.dadded)

這給了我期望的結果:

ItemID  Kit_MonthQty    Kit_MonthAsNumber   Kit_MonthAsString
13188   234             8                   August
13188   45              9                   September
13188   61              10                  October
13188   20              12                  December

在沒有數據存在的月份中,我該怎么做才能返回 ,如下所示:

ItemID  Kit_MonthQty    Kit_MonthAsNumber   Kit_MonthAsString
13188   0               1                   January
13188   0               2                   February
13188   0               3                   March
13188   0               4                   April
13188   0               5                   May
13188   0               6                   June
13188   0               7                   July
13188   234             8                   August
13188   45              9                   September
13188   61              10                  October
13188   0               11                  November
13188   20              12                  December

過去,我通過創建一個臨時表來解決這樣的問題,該表將保存所有需要的日期:

    CREATE TABLE #AllDates (ThisDate datetime null)
    SET @CurrentDate = @StartRange

    -- insert all dates into temp table
    WHILE @CurrentDate <=  @EndRange
        BEGIN
            INSERT INTO #AllDates values(@CurrentDate)
            SET @CurrentDate = dateadd(mm, 1, @CurrentDate)
        END

然后,修改查詢以針對該表進行聯接:

SELECT      ALLItems.ItemId,
            SUM(COALESCE(Inventory.Qty, 0)) AS Individual_MonthQty,
            MONTH(#AllDates.ThisDate) AS Individual_MonthAsNumber,
            DATENAME(MONTH, #AllDates.ThisDate) AS Individual_MonthAsString
FROM        #AllDates
            JOIN (SELECT DISTINCT dbo.Inventory.ItemId FROM dbo.Inventory)  AS ALLItems ON 1 = 1
            LEFT JOIN Inventory ON DATEADD(dd, - DAY(Inventory.dadded) +1, Inventory.dadded) = #AllDates.ThisDate AND ALLItems.ItemId = dbo.Inventory.ItemId
WHERE       
            #AllDates.ThisDate >= @StartRange
AND         #AllDates.ThisDate <= @EndRange
GROUP BY    ALLItems.ItemId, 
            #AllDates.ThisDate

然后,無論庫存中是否存在該記錄,您都應該有每個月的記錄。

您可以像這樣准備一個“日歷”表:

DECLARE @d datetime
SET @d = @StartRange

DECLARE @calendar TABLE (Date datetime)

WHILE (@d <= @EndRange) BEGIN
    INSERT INTO @Calendar VALUES (@d)
    SET @d = DATEADD(month, 1, @d)
END

然后對表進行月和年日期部分的LEFT JOIN 這樣,您始終可以將開始日期和結束日期之間的所有月份都作為行。

這是一種方法。 假設@StartRange@EndRange屬於同一日歷年,否則您會得到一些有趣的結果。

WITH n(n) AS 
(
    SELECT TOP 12 ROW_NUMBER() OVER (ORDER BY [object_id])
        FROM sys.objects
),
months(m, mn) AS
(
    SELECT n, DATENAME(MONTH, DATEADD(MONTH, m-1, '19000101')) 
        FROM n
)
SELECT 
    ItemID = i.itemid,
    MonthQty = COALESCE(SUM(TotalUnits), 0),
    MonthAsNumber = m.m,
    MonthAsString = m.mn
FROM
    months AS m
LEFT OUTER JOIN
    Inventory AS i
ON
    MONTH(i.dadded) = m.m
WHERE
    i.invtype = 'Shipment'
    AND i.dadded >= @StartRange
    AND i.dadded <= @EndRange
GROUP BY
    m.m, m.mn, i.itemid
ORDER BY m.m;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM