2013-05-29 92 views
4

假设我有两个记录,都与一个日期和计数:如何填补空白?

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

他们是很多文献,搜索'sql间隙和岛屿':示例:http://msdn.microsoft.com/en-us/library/aa175780(v=sql.80).aspx – danihp

+0

可能的重复[填充结果集中的每小时时间间隔](http://stackoverflow.com/questions/4504231/filling-in-the-hourly-time-gaps-in-a-resultset) – HABO

+0

@danihp谢谢。我会仔细看看它。 –

回答

4

您有2个问题想要解决。第一个问题是如何填补空白。第二个问题是为缺少的记录填充计数字段。

问题1:可以通过使用Dates Lookup table或创建recursive common table expression来解决此问题。如果这是一个选项,我建议为此创建一个日期查找表。如果你不能创建这样的表,那么你将需要这样的东西。

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步:有一个包含所有日期的日期表。 - 您可以使用许多方法,例如: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 

请让我知道,如果这个工程。我测试过,它工作。

+0

谢谢!问题是递归有100个限制。你知道如何避免这个问题吗? –

+1

你可以使用'OPTION(MAXRECURSION 0);'你可以粘贴你拥有的最后一个查询。我可以分析并告诉你。谢谢。 – RGV

+0

MAXRECURSION的绝对最大值为32767.谢谢。 –