从查询中插入缺少的日期


9

如何从我创建的查询中插入缺少的日期。结果如下:

Date          Frequency
2014-05-18    5
2014-05-20    7
2014-05-25    7
2014-05-27    6

我希望结果缺少具有0值的日期,如下所示:

Date          Frequency
2014-05-18    5
2014-05-19    0
2014-05-20    7
2014-05-21    0
2014-05-22    0
2014-05-23    0
2014-05-24    0
2014-05-25    7
2014-05-26    0
2014-05-27    6

请注意,我对服务器具有只读访问权限。


您是否在使用任何查询来获取结果?或者您是否定义了日期范围。您可以添加查询或表格

1
使用日历表,从选择,然后按日期加入到您的频率social.technet.microsoft.com/wiki/contents/articles/...
马克Sinkinson

我正在使用查询从主表中获取结果。
2014年

如果您具有只读访问权限,则不应插入或更新数据库。相反,请您的DBA团队帮助您。
Kin Shah 2014年

1
@Kin我认为这个问题意味着他们想在结果集中插入行,而不是在实际的数据库表中插入行。
马克·辛金森

Answers:


12

这是一个使用日历表的示例(您确实应该有)。该示例仅填充2014,但是您可以根据需要填入很多年...

CREATE TABLE dbo.Calendar(d DATE PRIMARY KEY);

INSERT dbo.Calendar(d) SELECT TOP (365)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, '20140101')
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number;

现在查询很简单:

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM dbo.Calendar AS c
  LEFT OUTER JOIN dbo.splunge AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle示例

如果您无法创建日历表(也没有方便的数字表),则可以将其内联:

DECLARE @s DATE = '20140518', @e DATE = '20140527';

SELECT c.d, Frequency = COALESCE(s.Frequency,0)
  FROM 
(
   SELECT TOP (DATEDIFF(DAY, @s, @e)+1)
 DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY number)-1, @s)
 FROM [master].dbo.spt_values
 WHERE [type] = N'P' ORDER BY number
) AS c(d)
  LEFT OUTER JOIN dbo.splunge2 AS s
  ON c.d = s.[date]
  WHERE c.d >= @s
    AND c.d < DATEADD(DAY, 1, @e);

SQLfiddle示例

有关生成集(日期,数字等)的更多信息,请参阅以下系列:


0
DECLARE @t TABLE(Dt Date,Frequency int)
INSERT INTO @t VALUES
('2014-05-18',5),('2014-05-20',7),('2014-05-25',7),('2014-05-27',6)



DECLARE @startDate DATE, @endDate DATE
SELECT @startDate = '2014-05-18', @endDate = '2014-05-27' --yyyy-mm-dd
;WITH Calender AS (
    SELECT @startDate AS CalanderDate
    UNION ALL
    SELECT DATEADD(day,1,CalanderDate) FROM Calender
    WHERE DATEADD(day,1,CalanderDate) <= @endDate
)
INSERT INTO @t SELECT
    Dt = CalanderDate,Frequency = 0

FROM Calender c
LEFT JOIN @t t 
ON t.Dt = c.CalanderDate
WHERE t.dt IS NULL
option (maxrecursion 0)

SELECT * FROM @t ORDER BY dt

小提琴

2014-05-18  5
2014-05-19  0
2014-05-20  7
2014-05-21  0
2014-05-22  0
2014-05-23  0
2014-05-24  0
2014-05-25  7
2014-05-26  0
2014-05-27  6

随着日期范围的扩大,递归CTE方法的成本成倍增加。有更有效的方法可以为此目的导出集合。
亚伦·伯特兰

@AaronBertrand这里的范围很小,但是有其他链接吗?出于我的好奇心。
Mihai 2014年

1
是的,这里的范围很小。问题是人们学习了这种方法,然后在出现问题的情况下将其大规模应用。在这种情况下,为什么仅因为它“正常”而使用慢速方法?看我的答案。
亚伦·伯特兰
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.