我想将具有StartTime和StopTime的表的每一行拆分为几天。
示例:
User Site Title TimeStampStart(01-11-2013) TimeStampStop(05-11-2013)
我希望在时间间隔中获得五行,其中包含日期:
User Site Title TimeStampStart(01-11-2013)
User Site Title TimeStampStart(02-11-2013)
User Site Title TimeStampStart(03-11-2013)
User Site Title TimeStampStart(04-11-2013)
User Site Title TimeStampStart(05-11-2013)
我创建了一个ListDates函数,允许我从两个时间戳中拆分数天但我不能使用它,因为我需要使用表作为参数。
答案 0 :(得分:3)
如果你有一个数字表,这是相当简单的。
CREATE TABLE dbo.Numbers(n INT PRIMARY KEY);
INSERT dbo.Numbers(n) SELECT TOP (1000) rn = ROW_NUMBER() OVER
(ORDER BY [object_id]) FROM sys.all_objects;
-- if you may have dates that may be more than 1000 days apart (~3 years),
-- increase TOP and use a cross join against one of the other system views
然后:
SELECT s.Site, DATEADD(DAY, n.n, TimeStampStart)
FROM dbo.YourTable AS s
INNER JOIN dbo.Numbers AS n
ON n.n <= DATEDIFF(DAY, s.TimeStampStart, s.TimeStampStop);
生成集合的许多示例(以及数字表通常最佳的原因):
http://sqlperformance.com/generate-a-set-1
答案 1 :(得分:0)
您可以使用系统表Master..spt_values来获取整数的顺序列表,并将其连接到您的源,每次将整数添加到开始日期(并在结束日期停止)。 e.g。
DECLARE @T TABLE (TimestampStart DATETIME2, TimestampStop DATETIME2);
INSERT @T VALUES ('20131101', '20131105');
SELECT Date = DATEADD(DAY, spt.Number, t.TimeStampStart)
FROM @t t
INNER JOIN master..spt_values spt
ON spt.Number <= DATEDIFF(DAY, t.TimestampStart, t.TimestampStop)
AND spt.Type = 'P';
如果您担心Microsoft会删除“未记录的”表格Master..spt_values
,或者您的日期将超过2047天,您可以另外一种方式生成您的号码列表:
DECLARE @T TABLE (TimestampStart DATETIME2, TimestampStop DATETIME2);
INSERT @T VALUES ('20131101', '20131105');
WITH Numbers AS
( SELECT TOP 100000 Number = ROW_NUMBER() OVER(ORDER BY a.Object_ID) - 1
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
)
SELECT Date = DATEADD(DAY, n.Number, t.TimestampStart)
FROM @T t
INNER JOIN Numbers n
ON n.Number <= DATEDIFF(DAY, t.TimestampStart, t.TimestampStop);
或者,创建您自己的数字表,可以反复使用,而无需在每次需要时动态生成数字表。