Как выбрать первый раз, только с интервалом более 5 минут - PullRequest
1 голос
/ 22 мая 2019
 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

Ответы [ 3 ]

1 голос
/ 23 мая 2019

Попробуйте это-

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)
    )
1 голос
/ 23 мая 2019

Сначала добавьте дату и время из предыдущей строки в каждую строку.Вы можете использовать светодиод, чтобы сделать это.Надеюсь, у вас есть 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

Результат:

enter image description here

1 голос
/ 22 мая 2019

Вы можете использовать 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));

дб <> скрипка

...