如何选择第一次输入,然后仅间隔大于 5 分钟
Posted
技术标签:
【中文标题】如何选择第一次输入,然后仅间隔大于 5 分钟【英文标题】:How to Select the first time entry, then only times greater than 5 minutes apart 【发布时间】:2019-05-22 19:52:15 【问题描述】: CREATE TABLE import_time
( date datetime NUll,
time datetime Null,
Employeeid nvarchar(25) Null)
INSERT INTO import_time (date, time, Employeeid)
Values ('2019-05-22 00:00:00.000', '1900-01-01 12:50:12.000', '1234')
, ('2019-05-22 00:00:00.000', '1900-01-01 12:55:00.000', '1234')
, ('2019-05-22 00:00:00.000', '1900-01-01 13:25:12.000', '1234')
, ('2019-05-22 00:00:00.000', '1900-01-01 13:50:12.000', '1234')
如何只选择第一次输入的时间,然后选择相隔大于 5 分钟的时间? 查询应返回 12:50、13:25 和 13:50 而不是 12:55 条目
【问题讨论】:
为什么将日期存储为datetime
并包含一个没有日期组件的时间列?这很奇怪。如果你有12:57:00
,会不会被选中?
我从中收集数据的程序将时间存储为日期时间数据类型。我只是在模拟我在更大的数据库中看到的内容。 -问候 B
@GordonLinoff 我在 sql 2000 和在日期和时间数据类型出现之前的几天里看到了许多类似的数据库。不是说这是一个好计划,只是我很久以前看到的。
最好使用标签来指定您正在使用的软件版本。这样您可以获得更好的答案
【参考方案1】:
首先将前一行的日期和时间添加到每一行。 您可以使用 LED 来做到这一点。希望您拥有 SQL Server 2012 及更高版本
您还应该注意午夜前后的时间,因为对于这些条目,如果您只比较时间可能会出错。
;with ct as (
select [date], [time], Employeeid
, prev_date = lag([date]) over (partition by Employeeid order by [date], [time])
, prev_time = lag([time]) over (partition by Employeeid order by [date], [time])
from #time
)
select [date], [time], Employeeid
from ct
where prev_date is null or prev_time is null -- this gives you the first entry
or datediff(minute, prev_date + prev_time, date + time) > 5
结果:
【讨论】:
【参考方案2】:您可以使用NOT EXISTS
来检查当前时间过去五分钟内是否没有其他行的时间更短或相等,我们使用dateadd()
得到。
要确定某行是否不是当前行,您需要一个键。在您的帖子中没有一个的情况下,我使用了未记录的 %%physloc%%
伪列作为代理。但无证意味着如有更改,恕不另行通知,因此您想替换它。
要修复拆分日期时间,您可以使用+
。
为方便起见,我使用 CTE 将原始表格准备为更可用的表格。
WITH
cte
AS
(
SELECT date,
time,
employeeid,
date + time datetime,
%%physloc%% physloc
FROM import_time
)
SELECT c1.date,
c1.time,
c1.employeeid
FROM cte c1
WHERE NOT EXISTS (SELECT *
FROM cte c2
WHERE c2.employeeid = c1.employeeid
AND c2.physloc <> c1.physloc
AND c2.datetime <= c1.datetime
AND c2.datetime > dateadd(minute, -5, c1.datetime));
db<>fiddle
【讨论】:
【参考方案3】:试试这个-
DECLARE @import_time TABLE
(
date datetime NUll,
time datetime Null,
Employeeid nvarchar(25) Null
)
INSERT INTO @import_time (date, time, Employeeid)
Values
('2019-05-22 00:00:00.000', '1900-01-01 12:50:12.000', '1234') ,
('2019-05-22 00:00:00.000', '1900-01-01 12:55:00.000', '1234') ,
('2019-05-22 00:00:00.000', '1900-01-01 13:25:12.000', '1234'),
('2019-05-22 00:00:00.000', '1900-01-01 13:50:12.000', '1234')
SELECT
CONVERT(VARCHAR(5),B.time ,108)
FROM
(
SELECT Employeeid,MIN ([time]) EnrtyTime
FROM @import_time
GROUP BY Employeeid
) A
INNER JOIN @import_time B
ON A.Employeeid = B.Employeeid
AND
(
A.EnrtyTime = B.time
OR
B.time >= DATEADD(MINUTE,5,A.EnrtyTime)
)
【讨论】:
以上是关于如何选择第一次输入,然后仅间隔大于 5 分钟的主要内容,如果未能解决你的问题,请参考以下文章