我的数据如下:
SKU StartDateTime EndDateTime
es311335 6/30/2013 5/24/2015
es311355 6/30/2013 6/28/2015
es311470 6/30/2013 12/14/2014
es311478 6/30/2013 6/28/2015
es311501 6/30/2013 6/28/2015
es311574 6/30/2013 6/28/2015
es311632 6/30/2013 6/22/2014
我希望它的格式为:
SKU Date
es311335 6/30/2013
es311335 7/7/2013
es311335 7/14/2013
es311335 7/21/2013
es311335 7/28/2013
es311335 8/4/2013
------ ------
es311335 24/05/2014
我使用了以下查询,但这并没有给我正确的结果。
DECLARE @Interval NVARCHAR(10), @I DATETIME,
@IntervalMin DATETIME, @IntervalMax DATETIME
--- Set Interval DAY or MONTH or YEAR -----------------
SET @Interval = 'DAY'
-------------------------------------------------------
DECLARE @Records TABLE
(StartDateTime DATETIME
,EndDateTime DATETIME)
INSERT INTO @Records
SELECT StartDateTime, EndDateTime
From records
DECLARE @Results TABLE
(StartDate DATETIME
,EndDate DATETIME)
WHILE EXISTS(SELECT * FROM @Records)
BEGIN
SELECT TOP 1 @IntervalMin = startdatetime, @IntervalMax = enddatetime
FROM @Records
SET @I = @IntervalMin
WHILE (@I <= @IntervalMax)
BEGIN
IF @Interval = 'DAY'
BEGIN
INSERT INTO @Results
SELECT @I, CASE WHEN CONVERT(DATE, DATEADD(DAY, 7, @I)) > @IntervalMax
THEN @IntervalMax ELSE CONVERT(DATE, DATEADD(DAY, 7, @I)) END
SET @I = CONVERT(DATE, DATEADD(DAY, 7, @I))
END
END
DELETE FROM @Records
WHERE startdatetime = @IntervalMin
AND enddatetime = @IntervalMax
END
SELECT *
FROM @Results
答案 0 :(得分:0)
我在评论中提到你应该使用计数表。这是我的计数表版本。我把它作为我系统中的一个视图,所以我不必永久地存储它,它会产生10,000行,读数为零。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
现在这又如何适用于你想要做的事情?我们可以使用一些日期数学来将计数表合并到一个基于集合的解决方案中,而不是RBAR(通过痛苦的行排)循环结构。在我们找到解决方案之前,我们必须以其他人可以使用的格式构建数据。
这是一种方法。
if OBJECT_ID('tempdb..#Something') is not null
drop table #Something
create table #Something
(
SKU char(9)
, StartDateTime datetime
, EndDateTime datetime
)
insert #Something
select 'es311335', '6/30/2013', '5/24/2015' union all
select 'es311355', '6/30/2013', '6/28/2015' union all
select 'es311470', '6/30/2013', '12/14/2014' union all
select 'es311478', '6/30/2013', '6/28/2015' union all
select 'es311501', '6/30/2013', '6/28/2015' union all
select 'es311574', '6/30/2013', '6/28/2015' union all
select 'es311632', '6/30/2013', '6/22/2014'
好酷。现在我们有一个计数表和一些数据可供使用。让我们看看当我们使用计数表时这是多么简单。
select s.*
, DATEADD(week, N - 1, StartDateTime)
from #Something s
join cteTally t on t.N <= DATEDIFF(week, StartDateTime, EndDateTime) + 1
order by SKU, DATEADD(week, N - 1, StartDateTime)