[英]Transposing Datetime Records in SQL Server
I'm working with the following table in SQL Server, which captures the start & end date/time for which an employee worked:我正在使用 SQL 服务器中的下表,该表捕获员工工作的开始和结束日期/时间:
EMP_NO RECORD_DATE START_TIME END_TIME
123456 2020-07-04 10:00:00.0000000 14:30:00.0000000
I need to transpose the date/time values, so that it generates incremental records at 30 minute intervals with the Date/time values concatenated:我需要转置日期/时间值,以便它以 30 分钟的间隔生成增量记录,并连接日期/时间值:
Expected Result:预期结果:
EMP_NO SHIFT_WORKED
123456 2020-07-04 10:00
123456 2020-07-04 10:30
123456 2020-07-04 11:00
123456 2020-07-04 11:30
123456 2020-07-04 12:00
123456 2020-07-04 12:30
123456 2020-07-04 13:00
123456 2020-07-04 13:30
123456 2020-07-04 14:00
Sample code:示例代码:
CREATE TABLE #HOURS (
EMP_NO INT NOT NULL,
RECORD_DATE DATETIME ,
START_TIME TIME NOT NULL,
END_TIME TIME NOT NULL
)
INSERT INTO #HOURS
VALUES (123456 ,' 2020-07-04',' 10:00',' 14:30')
A tally table will help you here. 计数表将在这里为您提供帮助。 (I prefer to call it an "integers table").
(我更喜欢称它为“整数表”)。 This is just a table of integers.
这只是一个整数表。 You can either actually have one persisted somewhere in the database, or create one "one the fly" with a CTE.
您可以在数据库中的某个地方实际保存一个,也可以使用 CTE 创建一个“one the fly”。 There are a lot of different ways to create such a thing, some faster than others!
有很多不同的方法可以创建这样的东西,有些方法比其他方法更快!
Once you have a tally table, you can generate any values that can be mathematically derived from that.一旦你有了一个计数表,你就可以生成任何可以从数学上推导出来的值。 In your case,
datetime
values in 30 minute increments.在您的情况下,
datetime
时间值以 30 分钟为增量。 You can then join that onto your date range.然后,您可以将其加入您的日期范围。 Here's one way which generates a tally table as a CTE
这是生成计数表作为 CTE 的一种方法
with integers as (
select top 1000 -- as many as you need
i = -1 + row_number() over (order by a.number) -- start from 0
from master..spt_values a
cross join master..spt_values b
)
select h.emp_no,
shift_worked = dateadd(minute, i * 30, t.startdt)
from #hours h
cross apply ( -- this cross apply just makes the join to integers easier to read
select startdt = h.record_Date + cast(h.start_Time as datetime),
enddt = h.record_date + cast(h.end_time as datetime)
) t
join integers i on dateadd(minute, i * 30, t.startdt) < t.enddt
you can do this:你可以这样做:
CREATE TABLE temp (EMP_NO INT ,SHIFT_WORKED datetime)
DECLARE @START_TIME TIME,@END_TIME TIME,@shift TIME,@emp int
SELECT @START_TIME=START_TIME,@END_TIME=END_TIME,@emp=EMP_NO FROM #HOURS
SET @shift=@START_TIME
WHILE DATEADD(MINUTE, 30, @shift) <=@END_TIME
BEGIN
INSERT INTO temp VALUES(@EMP,@shift)
SET @Shift = DATEADD(MINUTE, 30, @shift)
END
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.