Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何选择第一次输入,则每次间隔仅大于5分钟_Sql_Sql Server_Sql Server 2014 - Fatal编程技术网

Sql 如何选择第一次输入,则每次间隔仅大于5分钟

Sql 如何选择第一次输入,则每次间隔仅大于5分钟,sql,sql-server,sql-server-2014,Sql,Sql Server,Sql Server 2014,我如何只选择第一次输入的时间,然后选择间隔大于5分钟的时间? 查询应该返回12:50、13:25和13:50,而不是12:55条目您可以使用not EXISTS检查当前时间过去五分钟内没有其他时间小于或等于当前时间的行,这是我们使用dateadd得到的 要确定一行是否不是当前行,需要一个键。由于您的帖子中没有一个,我使用了未记录的%%physloc%%伪列作为代理。但“未记录”意味着可能会更改,恕不另行通知,所以您希望替换它 要修复分割日期时间,可以使用+ 为了方便起见,我使用CTE将原始表准备

我如何只选择第一次输入的时间,然后选择间隔大于5分钟的时间? 查询应该返回12:50、13:25和13:50,而不是12:55条目

您可以使用not EXISTS检查当前时间过去五分钟内没有其他时间小于或等于当前时间的行,这是我们使用dateadd得到的

要确定一行是否不是当前行,需要一个键。由于您的帖子中没有一个,我使用了未记录的%%physloc%%伪列作为代理。但“未记录”意味着可能会更改,恕不另行通知,所以您希望替换它

要修复分割日期时间,可以使用+

为了方便起见,我使用CTE将原始表准备成更有用的形式

 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')
试试这个-

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));

首先将前一行的日期和时间添加到每一行。 您可以使用LED来实现这一点。希望您有SQL Server 2012及更高版本

你也应该注意午夜前后的时间,因为对于那些条目,如果你只比较时间,你可能会出错

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)
    )
结果:


为什么要将日期存储为datetime并包含一个没有日期组件的时间列?这很奇怪。如果你选择了12:57:00,你会选择还是不选择?我收集数据的程序将时间存储为日期时间数据类型。我只是在模仿我在一个更大的数据库中看到的东西-当做B@GordonLinoff在sql 2000和更早的几天中,在有日期和时间数据类型之前,我看到了许多这样的数据库。并不是说这是一个好计划,这是我很久以前看到的。使用标签来指定您使用的软件版本总是很好的。这样你可以得到更好的答案
;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