2015-10-21 91 views
2

假設我有一個數據如下表:SQL - 在SQL累計總和,底座上連續日期

SELECT * 
FROM TestTable 
ORDER BY deliver_date 

deliver_date quantity 
2015-10-01 5.00 
2015-10-02 3.00 
2015-10-05 10.00 
2015-10-07 8.00 
2015-10-08 6.00 

我知道該怎麼做的累計如下:

SELECT t1.deliver_date, SUM(t2.quantity) AS cumQTY 
FROM TestTable t1 
INNER JOIN TestTable t2 ON t2.deliver_date <= t1.deliver_date 
GROUP BY t1.deliver_date 
ORDER BY t1.deliver_date 

結果:

deliver_date cumQTY 
2015-10-01 5.00 
2015-10-02 8.00 
2015-10-05 18.00 
2015-10-07 26.00 
2015-10-08 32.00 

但是,是否有可能得到如下結果?

deliver_date cumQTY 
2015-10-01 5.00 
2015-10-02 8.00 
2015-10-03 8.00 
2015-10-04 8.00 
2015-10-05 18.00 
2015-10-06 18.00 
2015-10-07 26.00 
2015-10-08 32.00 

意思是,日期必須連續。 例如:我的TestTable表中沒有2015-10-03的數據,但累積表必須顯示日期2015-10-03

感謝有人能幫助解決這個問題。 謝謝。

+0

什麼版本的SQL服務器您使用的是? –

+0

SQL-Server 2012 – Doraemon

回答

2

您可以使用Tally Table做到這一點:

SQL Fiddle

DECLARE @startDate DATE, 
     @endDate DATE 

SELECT 
    @startDate = MIN(deliver_date), 
    @endDate = MAX(deliver_date) 
FROM TestTable 

;WITH E1(N) AS(
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N) 
), 
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), 
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), 
Tally(N) AS(
    SELECT TOP(DATEDIFF(DAY, @startDate, @endDate) + 1) 
     ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) 
    FROM E4 
), 
CteAllDates AS(
    SELECT 
     deliver_date = DATEADD(DAY, t.N-1, @startDate), 
     quantity = ISNULL(tt.quantity, 0) 
    FROM Tally t 
    LEFT JOIN TestTable tt 
     ON DATEADD(DAY, N-1, @startDate) = tt.deliver_date 
) 
SELECT 
    deliver_date, 
    cumQty = SUM(quantity) OVER(ORDER BY deliver_date) 
FROM CteAllDates 

首先,要生成從MIN(deliver_date)開始到MAX(deliver_date)所有日期。這是通過使用計數表完成的,CTEE1(N)Tally(N)

現在你把所有的日期,原表,TestTableLEFT JOIN,以獲得相應的quantity,分配0如果沒有匹配的日期。

最後,要獲得累計總和,您可以使用SUM(quantity) OVER(ORDER BY deliver_date)


有關理貨表的詳細說明,請參閱我的answer here.