我简化了一个我被要求解决的问题。下面我有一张类似的表。
id: primary_key
person: varchar(20)
logdatetime: datetime
description: varchar(30)
使用此表,它以下列方式存储数据。
id person logdatetime description
-----------------------------------------------
4503 Joe 4/3/2018 11:00:00 Lunch
4504 Sam 4/3/2018 11:15:00 Lunch
4512 Joe 4/3/2018 12:05:00 Physics
4514 Sam 4/3/2018 12:05:00 Physics
4518 Sam 4/3/2018 13:05:00 Library
4521 Joe 4/3/2018 13:10:00 Language Arts
4522 Joe 4/3/2018 14:15:00 Day Complete
4526 Sam 4/3/2018 16:08:00 Day Complete
对于每个人,是否可以使用SQL来计算每个类/活动所花费的时间。在过去,我使用临时表将这些事件链接在一起,但这是一个实时系统,数据不断增长。理想的结果将如下所示。通过这样的数据结构,我可以轻松计算事件持续的总时间。
id person logdatetime enddatetime description
-------------------------------------------------------------------
4503 Joe 4/3/2018 11:00:00 4/3/2018/12:05:00 Lunch
4504 Sam 4/3/2018 11:15:00 4/3/2018 12:05:00 Lunch
4512 Joe 4/3/2018 12:05:00 4/3/2018 13:10:00 Physics
4514 Sam 4/3/2018 12:05:00 4/3/2018 13:05:00 Physics
4518 Sam 4/3/2018 13:05:00 4/3/2018 16:08:00 Library
4521 Joe 4/3/2018 13:10:00 4/3/2018 14:15:00 Language Arts
4522 Joe 4/3/2018 14:15:00 null Day Complete
4526 Sam 4/3/2018 16:08:00 null Day Complete
构建报告的好SQL选项是什么,它总结了在类/活动中花费的时间?我没有选择更改数据在此表中的存储方式。这适用于SQL Server数据库。
答案 0 :(得分:2)
让我们试试Joe
--just to get some sample data
if object_id('tempdb..#x') is not null drop table #x
CREATE TABLE #x(id INT, person VARCHAR(5), logdatetime DATETIME, description VARCHAR(20))
INSERT INTO #x(id,person,logdatetime,description) VALUES
(4503, 'Joe', '4/3/2018 11:00:00', 'Lunch'),
(4504, 'Sam', '4/3/2018 11:15:00', 'Lunch'),
(4512, 'Joe', '4/3/2018 12:05:00', 'Physics'),
(4514, 'Sam', '4/3/2018 12:05:00', 'Physics'),
(4518, 'Sam', '4/3/2018 13:05:00', 'Library'),
(4521, 'Joe', '4/3/2018 13:10:00', 'Language Arts'),
(4522, 'Joe', '4/3/2018 14:15:00', 'Day Complete'),
(4526, 'Sam', '4/3/2018 16:08:00', 'Day Complete')
--actual query
SELECT
description,
a.logdatetime AS 'Start',
(SELECT TOP 1 b.logdatetime FROM #x AS b WHERE b.person=a.person AND b.id>a.id ORDER BY b.id) AS 'End',
DATEDIFF(minute,a.logdatetime,
(SELECT TOP 1 b.logdatetime FROM #x AS b WHERE b.person=a.person AND b.id>a.id ORDER BY b.id) ) AS 'TimeDiff(Min)'
FROM #x AS a
WHERE a.person='Joe'
输出
description Start End TimeDiff(Min)
Lunch 2018-04-03 11:00:00.000 2018-04-03 12:05:00.000 65
Physics 2018-04-03 12:05:00.000 2018-04-03 13:10:00.000 65
Language Arts 2018-04-03 13:10:00.000 2018-04-03 14:15:00.000 65
Day Complete 2018-04-03 14:15:00.000 NULL NULL
答案 1 :(得分:2)
这是使用LEAD()
的版本(如果你有2012 +)
if object_id('tempdb.dbo.#x') is not null drop table #x
create table #x
(
Id int,
Person varchar(5),
LogDateTime datetime,
Description varchar(20)
)
insert into #x
(
id,
person,
logdatetime,
description
)
values
(4503, 'Joe', '4/3/2018 11:00:00', 'Lunch'),
(4504, 'Sam', '4/3/2018 11:15:00', 'Lunch'),
(4512, 'Joe', '4/3/2018 12:05:00', 'Physics'),
(4514, 'Sam', '4/3/2018 12:05:00', 'Physics'),
(4518, 'Sam', '4/3/2018 13:05:00', 'Library'),
(4521, 'Joe', '4/3/2018 13:10:00', 'Language Arts'),
(4522, 'Joe', '4/3/2018 14:15:00', 'Day Complete'),
(4526, 'Sam', '4/3/2018 16:08:00', 'Day Complete')
select
Id,
Person,
LogDateTime,
EndDateTime = lead(LogDateTime, 1, null) over (partition by Person order by (Id)),
Description
from #x
order by id
答案 2 :(得分:1)
SELECT id, person, logdatetime,
LEAD(logdatetime, 1,null) OVER (PARTITION BY person ORDER BY id) AS enddatetime, description
FROM test
ORDER BY id
答案 3 :(得分:0)
尝试使用铅
在几分钟内获得时间SELECT Person, description, logdatetime,
CASE WHEN TimeSpent < 0 THEN 0 ELSE TimeSpent END AS TimeSpent
FROM (SELECT Person, description, logdatetime,
(DATEDIFF(MINUTE,logdatetime,LEAD(logdatetime,1,0) OVER (PARTITION BY person ORDER BY id))) AS TimeSpent FROM Tempx) AS SEL