Code:
DECLARE @T1 TABLE ([ID] INT, [WD] DATE, [SD] DATETIME, [ED] DATETIME, [Val] INT)
INSERT INTO @T1 ( [ID], [WD], [SD], [ED], [VAL] )
VALUES ( 1, '2016-02-14', '2016-02-14 08:00:00', '2016-02-14 16:30:00', 12 )
,( 1, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 15 )
,( 3, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 12 )
,( 1, '2016-02-21', '2016-02-22 08:00:00', '2016-02-22 16:30:00', 100 )
,( 2, '2016-02-21', '2016-02-25 08:00:00', '2016-02-25 16:30:00', 124 )
,( 3, '2016-03-20', '2016-03-21 08:00:00', '2016-03-21 16:30:00', 10 )
,( 3, '2016-04-17', '2016-04-17 08:00:00', '2016-04-17 16:30:00', 8 );
DECLARE @StartDate DATE
, @EndDate DATE;
SELECT @StartDate = MIN(WD) FROM @T1
SELECT @EndDate = DATEADD(DAY,6,MAX(WD)) FROM @T1;
DECLARE @T2 TABLE (D DATE) -- Table generated to get ALL dates between the minium WD (Min Sunday) and 6 days after the maximum WD (Max Sunday + 6 days to complete the week date range)
INSERT INTO @T2 ( [D] )
SELECT DATEADD(DAY, NBR - 1, @StartDate)
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY c.object_id ) AS NBR
FROM sys.columns c
) NBR
WHERE NBR - 1 <= DATEDIFF(DAY, @StartDate, @EndDate);
SELECT * FROM @T1;
SELECT * FROM @T2;
Description: @T1 is the pre-populated source data table with specific dates where [ID] = an ID field of some sort, [WD] = Different start of the week (Sundays), [SD] = Start of a day within that [WD] week, [ED] = End of a day within that [WD] week, [Val] = Some assigned value for that ID/WD/SD/ED record
说明:@ T1是预先填充的源数据表,其中包含特定日期,其中[ID] =某种ID字段,[WD] =不同的星期开始(星期日),[SD] =一天中的一天开始[WD]周,[ED] = [WD]周内一天的结束,[Val] =该ID / WD / SD / ED记录的某些指定值
@T2 is the table I'm defining and populating to get all the dates within MIN([WD]) and MAX([WD]) + 6 days (to compelte the week)
@T2是我正在定义和填充的表,以获得MIN([WD])和MAX([WD])+ 6天内的所有日期(以强制一周)
Goal:
Return @T1 data along with any missing dates for those [ID]/[WD] weeks. (refer to Desired Output for better understanding)
返回@ T1数据以及[ID] / [WD]周的任何缺失日期。 (请参阅所需输出以便更好地理解)
Desired result (copied from Excel so the format is different, but that's ok)
期望的结果(从Excel复制,因此格式不同,但没关系)
[ID][WD] [SD] [ED] [Val]
1 2/14/2016 2/14/16 8:00 2/14/16 16:30 12
1 2/14/2016 2/15/16 00:00 2/15/16 00:00 NULL
1 2/14/2016 2/16/16 8:00 2/16/16 16:30 15
1 2/14/2016 2/17/16 00:00 2/17/16 00:00 NULL
1 2/14/2016 2/18/16 00:00 2/18/16 00:00 NULL
1 2/14/2016 2/19/16 00:00 2/19/16 00:00 NULL
1 2/14/2016 2/20/16 00:00 2/20/16 00:00 NULL
3 2/14/2016 2/14/16 00:00 2/14/16 00:00 NULL
3 2/14/2016 2/15/16 00:00 2/15/16 00:00 NULL
3 2/14/2016 2/16/16 8:00 2/16/16 16:30 12
3 2/14/2016 2/17/16 00:00 2/17/16 00:00 NULL
3 2/14/2016 2/18/16 00:00 2/18/16 00:00 NULL
3 2/14/2016 2/19/16 00:00 2/19/16 00:00 NULL
3 2/14/2016 2/20/16 00:00 2/20/16 00:00 NULL
1 2/21/2016 2/21/16 00:00 2/21/16 00:00 NULL
1 2/21/2016 2/22/16 8:00 2/22/16 16:30 100
1 2/21/2016 2/23/16 00:00 2/23/16 00:00 NULL
1 2/21/2016 2/24/16 00:00 2/24/16 00:00 NULL
1 2/21/2016 2/25/16 00:00 2/25/16 00:00 NULL
1 2/21/2016 2/26/16 00:00 2/26/16 00:00 NULL
1 2/21/2016 2/27/16 00:00 2/27/16 00:00 NULL
2 2/21/2016 2/21/16 00:00 2/21/16 00:00 NULL
2 2/21/2016 2/22/16 00:00 2/22/16 00:00 NULL
2 2/21/2016 2/23/16 00:00 2/23/16 00:00 NULL
2 2/21/2016 2/24/16 00:00 2/24/16 00:00 NULL
2 2/21/2016 2/25/16 8:00 2/25/16 16:30 124
2 2/21/2016 2/26/16 00:00 2/26/16 00:00 NULL
2 2/21/2016 2/27/16 00:00 2/27/16 00:00 NULL
3 3/20/2016 3/20/16 00:00 3/20/16 00:00 NULL
3 3/20/2016 3/21/16 8:00 3/21/16 16:30 10
3 3/20/2016 3/22/16 00:00 3/22/16 00:00 NULL
3 3/20/2016 3/23/16 00:00 3/23/16 00:00 NULL
3 3/20/2016 3/24/16 00:00 3/24/16 00:00 NULL
3 3/20/2016 3/25/16 00:00 3/25/16 00:00 NULL
3 3/20/2016 3/26/16 00:00 3/26/16 00:00 NULL
3 4/17/2016 4/17/16 8:00 4/17/16 16:30 8
3 4/17/2016 4/18/16 00:00 4/18/16 00:00 NULL
3 4/17/2016 4/19/16 00:00 4/19/16 00:00 NULL
3 4/17/2016 4/20/16 00:00 4/20/16 00:00 NULL
3 4/17/2016 4/21/16 00:00 4/21/16 00:00 NULL
3 4/17/2016 4/22/16 00:00 4/22/16 00:00 NULL
3 4/17/2016 4/23/16 00:00 4/23/16 00:00 NULL
I tried using cross join and stuff but no luck with getting the desired output.
我尝试使用交叉连接和东西,但没有运气获得所需的输出。
2 个解决方案
#1
3
I removed your @T2 and use my @T3 instead.
我删除了你的@ T2并使用我的@ T3代替。
DECLARE @T1 TABLE ([ID] INT, [WD] DATE, [SD] DATETIME, [ED] DATETIME, [Val] INT)
INSERT INTO @T1 ( [ID], [WD], [SD], [ED], [VAL] )
VALUES ( 1, '2016-02-14', '2016-02-14 08:00:00', '2016-02-14 16:30:00', 12 )
,( 1, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 15 )
,( 3, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 12 )
,( 1, '2016-02-21', '2016-02-22 08:00:00', '2016-02-22 16:30:00', 100 )
,( 2, '2016-02-21', '2016-02-25 08:00:00', '2016-02-25 16:30:00', 124 )
,( 3, '2016-03-20', '2016-03-21 08:00:00', '2016-03-21 16:30:00', 10 )
,( 3, '2016-04-17', '2016-04-17 08:00:00', '2016-04-17 16:30:00', 8 );
DECLARE @T3 TABLE ([ID] INT, [WD] DATE, [SD] DATETIME, [ED] DATETIME);
WITH cte AS (
SELECT DISTINCT ID, WD
FROM
@T1
)
INSERT INTO @T3 (ID, WD, SD, ED)
SELECT ID, WD, DATEADD(DAY,n,WD), DATEADD(DAY,n,WD)
FROM
cte
CROSS JOIN (VALUES (0),(1),(2),(3),(4),(5),(6)) AS ADDED(n);
SELECT t3.ID, t3.WD,COALESCE(t1.SD,t3.SD) AS SD, COALESCE(t1.ED,t3.ED) AS ED, t1.Val
FROM @T3 t3
LEFT JOIN @T1 t1 ON t3.ID=t1.ID AND CONVERT(DATE,t1.SD)=CONVERT(DATE,t3.SD)
#2
2
This would be a left join of your source data against the timeline you created.
这将是源数据与您创建的时间轴的左连接。
I could not figure out how the ID is assigned, but when I use COALESCE to fill up missing values this returns your desired output (except ID):
我无法弄清楚如何分配ID,但是当我使用COALESCE填充缺失值时,这将返回所需的输出(ID除外):
SELECT [t1].[ID]
,COALESCE([t1].[WD], DATEADD(DAY, 1 - DATEPART(WEEKDAY, [t2].[D]), [t2].[D])) AS WD
,COALESCE([t1].[SD], [t2].[D]) AS SD
,COALESCE([t1].[ED], [t2].[D]) AS ED
,[t1].[Val]
FROM @T2 [t2]
LEFT JOIN @T1 [t1]
ON [t2].[D] = CONVERT(DATE, [t1].[SD]);
#1
3
I removed your @T2 and use my @T3 instead.
我删除了你的@ T2并使用我的@ T3代替。
DECLARE @T1 TABLE ([ID] INT, [WD] DATE, [SD] DATETIME, [ED] DATETIME, [Val] INT)
INSERT INTO @T1 ( [ID], [WD], [SD], [ED], [VAL] )
VALUES ( 1, '2016-02-14', '2016-02-14 08:00:00', '2016-02-14 16:30:00', 12 )
,( 1, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 15 )
,( 3, '2016-02-14', '2016-02-16 08:00:00', '2016-02-16 16:30:00', 12 )
,( 1, '2016-02-21', '2016-02-22 08:00:00', '2016-02-22 16:30:00', 100 )
,( 2, '2016-02-21', '2016-02-25 08:00:00', '2016-02-25 16:30:00', 124 )
,( 3, '2016-03-20', '2016-03-21 08:00:00', '2016-03-21 16:30:00', 10 )
,( 3, '2016-04-17', '2016-04-17 08:00:00', '2016-04-17 16:30:00', 8 );
DECLARE @T3 TABLE ([ID] INT, [WD] DATE, [SD] DATETIME, [ED] DATETIME);
WITH cte AS (
SELECT DISTINCT ID, WD
FROM
@T1
)
INSERT INTO @T3 (ID, WD, SD, ED)
SELECT ID, WD, DATEADD(DAY,n,WD), DATEADD(DAY,n,WD)
FROM
cte
CROSS JOIN (VALUES (0),(1),(2),(3),(4),(5),(6)) AS ADDED(n);
SELECT t3.ID, t3.WD,COALESCE(t1.SD,t3.SD) AS SD, COALESCE(t1.ED,t3.ED) AS ED, t1.Val
FROM @T3 t3
LEFT JOIN @T1 t1 ON t3.ID=t1.ID AND CONVERT(DATE,t1.SD)=CONVERT(DATE,t3.SD)
#2
2
This would be a left join of your source data against the timeline you created.
这将是源数据与您创建的时间轴的左连接。
I could not figure out how the ID is assigned, but when I use COALESCE to fill up missing values this returns your desired output (except ID):
我无法弄清楚如何分配ID,但是当我使用COALESCE填充缺失值时,这将返回所需的输出(ID除外):
SELECT [t1].[ID]
,COALESCE([t1].[WD], DATEADD(DAY, 1 - DATEPART(WEEKDAY, [t2].[D]), [t2].[D])) AS WD
,COALESCE([t1].[SD], [t2].[D]) AS SD
,COALESCE([t1].[ED], [t2].[D]) AS ED
,[t1].[Val]
FROM @T2 [t2]
LEFT JOIN @T1 [t1]
ON [t2].[D] = CONVERT(DATE, [t1].[SD]);