假设我有两条记录,都有日期和计数:
--Date-- --Count--
2011-09-20 00:00:00 5
2011-09-16 00:00:00 8
你如何选择这个填补时间空白,总是记录最后一个记录?
所以输出结果为:
--Date-- --Count--
2011-09-20 00:00:00 5
2011-09-19 00:00:00 8
2011-09-18 00:00:00 8
2011-09-17 00:00:00 8
2011-09-16 00:00:00 8
我无法找到一个简洁的解决方案。 我想这可以用DATEDIFF和for循环来完成,但我希望这可以更轻松。
答案 0 :(得分:4)
您有2个问题正在尝试解决。第一个问题是如何填补空白。第二个问题是为那些丢失的记录填充Count字段。
问题1:可以使用Dates Lookup table
或创建recursive common table expression
来解决此问题。如果这是一个选项,我建议为此创建一个Dates Lookup表。如果你不能创建这样的表,那么你将需要这样的东西。
WITH CTE AS (
SELECT MAX(dt) maxdate, MIN(dt) mindate
FROM yourtable
),
RecursiveCTE AS (
SELECT mindate dtfield
FROM CTE
UNION ALL
SELECT DATEADD(day, 1, dtfield)
FROM RecursiveCTE R
JOIN CTE T
ON R.dtfield < T.maxdate
)
这应该会为您创建一个日期列表,其中包含表格中的MIN
日期,并以MAX
结尾。
问题2:这里有一个correlated subquery
会派上用场(尽管我通常会远离它们)从原始表中获取最后一个cnt:
SELECT r.dtfield,
(SELECT TOP 1 cnt
FROM yourtable
WHERE dt <= r.dtfield
ORDER BY dt DESC) cnt
FROM RecursiveCTE r
答案 1 :(得分:1)
我的解决方案是这样的。
步骤1:拥有一个包含所有日期的日期表。 - 您可以使用许多方法:Get a list of dates between two dates
步骤2:从日期表到结果集的左外边框。 - 这将导致您使用以下结果集:将此表称为“TEST_DATE_COUnt”
--Date-- --Count--
2011-09-20 00:00:00 5
2011-09-19 00:00:00 0
2011-09-18 00:00:00 0
2011-09-17 00:00:00 0
2011-09-16 00:00:00 8
步骤3:执行如下的递归查询:
SELECT t1.date_x, t1.count_x,
(case when count_x=0 then (SELECT max(COUNT_X)
FROM TEST_DATE_COUNT r
WHERE r.DATE_X <= t1.DATE_X)
else COUNT_X
end)
cnt
FROM TEST_DATE_COUNT t1
如果有效,请告诉我。我测试过它。