假设我有一个包含以下数据的表:
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 :(得分:2)
您可以使用Tally Table:
执行此操作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)
的所有日期。这是使用计数表完成的,CTE
从E1(N)
到Tally(N)
。
现在您已拥有所有日期,请在原始表LEFT JOIN
上执行TestTable
,以获取相应的quantity
,如果没有匹配则指定0
日期。
最后,要获得累计金额,您可以使用SUM(quantity) OVER(ORDER BY deliver_date)
。
有关计数表的更多说明,请参阅我的answer here.