【发布时间】:2019-09-13 16:10:45
【问题描述】:
我有一个表格,它代表特定日期的工作小时数。从该表中,我希望能够向代表前 7 天工作时间的每一行再添加 7 列。
我一直在使用 LAG() 来完成此操作,并且它工作正常,直到我发现一个问题,即我在几天之间存在差距,现在我选择前 7 行而不是选择前 7 天。
这个脚本演示了我想要完成的事情。
DECLARE @data TABLE (
[user_id] int,
[date] DATETIME,
[day_hours_worked] VARCHAR(15)
);
INSERT INTO @data
VALUES
( '1', '2019-09-07 00:00:00.000', '07_8' )
, ( '1', '2019-09-08 00:00:00.000', '08_4' )
, ( '1', '2019-09-09 00:00:00.000', '09_6' )
, ( '1', '2019-09-10 00:00:00.000', '10_8' )
, ( '1', '2019-09-11 00:00:00.000', '11_4' )
, ( '1', '2019-09-12 00:00:00.000', '12_6' )
, ( '1', '2019-09-13 00:00:00.000', '13_8' )
, ( '1', '2019-09-14 00:00:00.000', '14_4' )
, ( '1', '2019-09-20 00:00:00.000', '20_8' );
select
[user_id],
[date],
[day_hours_worked],
LAG([day_hours_worked], 1) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-1],
LAG([day_hours_worked], 2) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-2],
LAG([day_hours_worked], 3) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-3],
LAG([day_hours_worked], 4) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-4],
LAG([day_hours_worked], 5) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-5],
LAG([day_hours_worked], 6) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-6],
LAG([day_hours_worked], 7) OVER (PARTITION BY [user_id] ORDER BY [date]) [Hours-7]
from @data
这就是我得到的。
user_id date day_hours_worked Hours-1 Hours-2 Hours-3 Hours-4 Hours-5 Hours-6 Hours-7
1 2019-09-07 00:00:00.000 07_8 NULL NULL NULL NULL NULL NULL NULL
1 2019-09-08 00:00:00.000 08_4 07_8 NULL NULL NULL NULL NULL NULL
1 2019-09-09 00:00:00.000 09_6 08_4 07_8 NULL NULL NULL NULL NULL
1 2019-09-10 00:00:00.000 10_8 09_6 08_4 07_8 NULL NULL NULL NULL
1 2019-09-11 00:00:00.000 11_4 10_8 09_6 08_4 07_8 NULL NULL NULL
1 2019-09-12 00:00:00.000 12_6 11_4 10_8 09_6 08_4 07_8 NULL NULL
1 2019-09-13 00:00:00.000 13_8 12_6 11_4 10_8 09_6 08_4 07_8 NULL
1 2019-09-14 00:00:00.000 14_4 13_8 12_6 11_4 10_8 09_6 08_4 07_8
1 2019-09-20 00:00:00.000 20_8 14_4 13_8 12_6 11_4 10_8 09_6 08_4
最后一行是唯一不正确的行,因为它查看的是前 7 行而不是前 7 天。在我的场景中,预期的结果应该是:
user_id date day_hours_worked Hours-1 Hours-2 Hours-3 Hours-4 Hours-5 Hours-6 Hours-7
1 2019-09-07 00:00:00.000 07_8 NULL NULL NULL NULL NULL NULL NULL
1 2019-09-08 00:00:00.000 08_4 07_8 NULL NULL NULL NULL NULL NULL
1 2019-09-09 00:00:00.000 09_6 08_4 07_8 NULL NULL NULL NULL NULL
1 2019-09-10 00:00:00.000 10_8 09_6 08_4 07_8 NULL NULL NULL NULL
1 2019-09-11 00:00:00.000 11_4 10_8 09_6 08_4 07_8 NULL NULL NULL
1 2019-09-12 00:00:00.000 12_6 11_4 10_8 09_6 08_4 07_8 NULL NULL
1 2019-09-13 00:00:00.000 13_8 12_6 11_4 10_8 09_6 08_4 07_8 NULL
1 2019-09-14 00:00:00.000 14_4 13_8 12_6 11_4 10_8 09_6 08_4 07_8
1 2019-09-20 00:00:00.000 20_8 NULL NULL NULL NULL NULL 14_4 13_8
这甚至可以使用 LAG() 吗?有没有更好的方法来完成我想要的?
提前致谢。
【问题讨论】:
-
一个更相关的问题是,为什么您首先需要这样做?你想完成什么?
-
外部联接到保证每个日期有一行的日历表,然后像以前一样继续使用
LAG -
@iamdave 我需要这样做,因为我可以访问前 7 天每天在一行中工作的时间。这是因为我正在使用这些数据来提供一个报告,该报告对上一行或下一行一无所知,需要它进行一些计算。
-
@MartinSmith 你能提供一些代码吗?
-
没时间,但概念很简单。在可预见的将来,为感兴趣的范围内的每个日期创建一个日历表,其中每个日期都有一行。选择感兴趣期间的 where 子句。这为您提供每个日期一行,现在外部连接到您的原始表,每个日期您仍然有一行,因此您不会遇到缺少行的问题,并且您的
LAG方法计数行仍然有效
标签: sql sql-server tsql datetime