Выбор данных верхней строки в той же строке (если разница данных меньше, чем 'n' часов в том же столбце) sql - PullRequest
1 голос
/ 10 января 2020

У меня есть существующие данные, которые нужно отсортировать, моя проблема в том, как отсортировать данные в одном столбце, если разница между значениями составляет менее 3 часов, будет выбрано самое высокое значение.

Это правдоподобно?

На основании приведенной ниже таблицы, 2019-12-25 имеет 3 значения,

| 2019-12-25 14:00:02.000 | 2019-12-25 |
| 2019-12-25 15:39:57.000 | 2019-12-25 |
| 2019-12-25 22:39:57.000 | 2019-12-25 | 

Я хочу удалить 2019 -12-25 14: 00: 02.000 из списка, чтобы оставшиеся данные были 2019-12-25 15: 39: 57.000 и 2019-12-25 22 : 39: 57.000 .

Поток, которого я пытаюсь добиться, заключается в том, что если разница между датой и часами между отметками времени не превышает 3 часа, будет выбрано только самое высокое значение, в этом сценарии 2019- 12-25 15: 39: 57.000 будут выбраны с 2019-12-25 14: 00: 02.000 и 2019-12-25 15: 39: 57.000 находятся в пределах одного 3-часового диапазона, а 2019-12-25 22:39 : 57.000 останутся в таблице с момента выхода за пределы 3 часов по сравнению с двумя значениями.

Есть ли способ, чтобы это сработало?

 +-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| badgenumber | checktype | recordout               | checkdate  | employeeidno | fullname | departmentname |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-21 23:43:36.000 | 2019-12-21 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-22 22:36:50.000 | 2019-12-22 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-23 18:03:16.000 | 2019-12-23 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-24 22:06:58.000 | 2019-12-24 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 14:00:02.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 15:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 22:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-26 14:00:02.000 | 2019-12-26 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-28 22:00:01.000 | 2019-12-28 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-28 23:31:11.000 | 2019-12-28 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-29 15:08:10.000 | 2019-12-29 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-30 16:03:20.000 | 2019-12-30 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-02 06:52:18.000 | 2020-01-02 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-03 08:00:57.000 | 2020-01-03 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-04 06:40:11.000 | 2020-01-04 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+

Пример.

+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| badgenumber | checktype | recordout               | checkdate  | employeeidno | fullname | departmentname |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 14:00:02.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 15:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 22:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+

Разница между 2 временными метками составляет менее 3 часов. Таким образом, 3: 39: 57 PM будет выбрано взамен, а 10: 39: 57 PM будет проигнорировано и останется в таблице, поскольку его путь превышает 3 часа по сравнению с другими 2 данных в одном столбце.

main data

Это мой ожидаемый результат.

+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| badgenumber | checktype | recordout               | checkdate  | employeeidno | fullname | departmentname |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-21 23:43:36.000 | 2019-12-21 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-22 22:36:50.000 | 2019-12-22 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-23 18:03:16.000 | 2019-12-23 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-24 22:06:58.000 | 2019-12-24 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 14:00:02.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 15:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-25 22:39:57.000 | 2019-12-25 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-26 14:00:02.000 | 2019-12-26 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-28 22:00:01.000 | 2019-12-28 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-28 23:31:11.000 | 2019-12-28 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-29 15:08:10.000 | 2019-12-29 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2019-12-30 16:03:20.000 | 2019-12-30 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-02 06:52:18.000 | 2020-01-02 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-03 08:00:57.000 | 2020-01-03 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+
| 1233        | O         | 2020-01-04 06:40:11.000 | 2020-01-04 |              |          |                |
+-------------+-----------+-------------------------+------------+--------------+----------+----------------+

Это часть моего кода где мне это нужно для работы.

                    (SELECT MAX(userinfo.badgenumber) AS badgenumber, MAX(RTRIM(checkinout.checktype)) AS 'checktype', 
                    MAX(checkinout.checktime) as 'recordout', MAX(CONVERT(date,checkinout.checktime)) as checkdate, 
                    MAX(RTRIM(employeemasterfile.employeeidno)) AS 'employeeidno', MAX(RTRIM(employeemasterfile.lastname))+', '+ 
                    MAX(RTRIM(employeemasterfile.firstname))+' '+MAX(LEFT(employeemasterfile.middlename,1))+'.' AS 'fullname', 
                    MAX(RTRIM(departmentmasterfile.departmentname)) AS 'departmentname' FROM ((checkinout INNER JOIN userinfo 
                    ON checkinout.userid = userinfo.userid) INNER JOIN employeemasterfile ON userinfo.badgenumber = employeemasterfile.fingerscanno) 
                    INNER JOIN departmentmasterfile ON LEFT(employeemasterfile.employeeidno, 4) = LEFT(departmentmasterfile.departmentcode, 4) 
                    WHERE CONVERT(date,checkinout.checktime) BETWEEN '2019-12-21' AND DATEADD(DAY, 1,'2020-01-05') AND fingerscanno = '1233'
                    AND CHECKINOUT.CHECKTYPE = 'O' COLLATE SQL_Latin1_General_CP1_CS_AS GROUP BY userinfo.badgenumber, LEFT(checkinout.checktime,14)) AS t2
                    ON 
                    t2.recordout BETWEEN DATEADD(HOUR,-6,t0.mergetimeoutorig) AND DATEADD(HOUR, 6,t0.mergetimeoutorig)

Пример значения t0.mergetimeoutorig = 25/12/2019

Ответы [ 2 ]

1 голос
/ 10 января 2020

Попробуйте реализовать нижеприведенную логику c в вашем запросе

     --Table where swipe details are stored
            Create table #EmployeeSwipe
            (
            ID INT IDENTITY(1,1) primary key,
            EmployeeID INT,
            CheckType varchar(10),
            SwipeTime DATETIME,
            SwipeDate DATE
            )
        GO
    --this table will have filtered row id's
        CREATE Table #tempdata
        (
        RowID INT 
        )
        GO
    --Dump data
        Insert into #EmployeeSwipe values(
        1,'I','2019-12-27 10:43:36.000','12/27/2019'
        )

        Insert into #EmployeeSwipe values(
        1,'O','2019-12-27 14:43:36.000','12/27/2019'
        )

        Insert into #EmployeeSwipe values(
        1,'O','2019-12-27 15:43:36.000','12/27/2019'
        )

        Insert into #EmployeeSwipe values(
        1,'O','2019-12-27 22:43:36.000','12/27/2019'
        )

        Insert into #EmployeeSwipe values(
        2,'O','2019-12-27 14:43:36.000','12/27/2019'
        )
        Insert into #EmployeeSwipe values(
        2,'O','2019-12-27 15:43:36.000','12/27/2019'
        )

        Insert into #EmployeeSwipe values(
        3,'O','2019-12-27 14:43:36.000','12/27/2019'
        )
        GO

        ;with cteres
        AS
        (
        SELECT
        P.ID,P.EmployeeID ,P.SwipeDate ,
            p.SwipeTime,
            LEAD(p.SwipeTime) OVER(Partition By P.EmployeeID ORDER BY P.ID) NextValue
        FROM #EmployeeSwipe P Where checktype='O'
        )

  --Here check if difference between two swap time is more than 3 hours    
        Insert into #tempdata
        select ID from 
        (select CASE WHEN 
                DATEDIFF(HOUR,SwipeTime,NextValue) > 3 THEN 1
                WHEN DATEDIFF(HOUR,SwipeTime,NextValue) IS NULL THEN 1
                ELSE 0 END as IsValid,ID from cteres
        ) --where NextValue is not null)
        mres where mres.IsValid = 1

--This will give you final output
        select ES.* from #tempdata T JOIN #EmployeeSwipe ES ON T.RowID = ES.ID
1 голос
/ 10 января 2020

Следующий код даст вам даты, которые необходимо исключить.

SELECT DS.*
FROM @DataSource DS1
CROSS APPLY
(
    SELECT *
    FROM @DataSource DS2
    WHERE DS1.[checkdate] = DS2.[checkdate]
        AND DATEDIFF(HOUR, DS1.[recordout], DS2.[recordout]) < 3
        AND DS1.[recordout] < DS2.[recordout]
) DS;

Тогда вы можете DELETE из исходной таблицы или SELECT только необходимые данные. Вот полный рабочий пример:

DECLARE @DataSource TABLE
(
    [recordout] DATETIME
   ,[checkdate] DATE
);

INSERT INTO @DataSource ([recordout], [checkdate])
VALUES ('2019-12-21 23:43:36.000', '2019-12-21')
      ,('2019-12-22 22:36:50.000', '2019-12-22')
      ,('2019-12-23 18:03:16.000', '2019-12-23')
      ,('2019-12-24 22:06:58.000', '2019-12-24')
      ,('2019-12-25 01:39:57.000', '2019-12-25')
      ,('2019-12-25 02:39:57.000', '2019-12-25')
      ,('2019-12-25 02:49:57.000', '2019-12-25')
      ,('2019-12-25 14:00:02.000', '2019-12-25')
      ,('2019-12-25 15:39:57.000', '2019-12-25')
      ,('2019-12-25 22:39:57.000', '2019-12-25')
      ,('2019-12-26 14:00:02.000', '2019-12-26')
      ,('2019-12-28 22:00:01.000', '2019-12-28')
      ,('2019-12-28 23:31:11.000', '2019-12-28')
      ,('2019-12-29 15:08:10.000', '2019-12-29')
      ,('2019-12-30 16:03:20.000', '2019-12-30')
      ,('2020-01-02 06:52:18.000', '2020-01-02')
      ,('2020-01-03 08:00:57.000', '2020-01-03')
      ,('2020-01-04 06:40:11.000', '2020-01-04');

WITH DataSource AS
(
    SELECT DS.*
    FROM @DataSource DS1
    CROSS APPLY
    (
        SELECT *
        FROM @DataSource DS2
        WHERE DS1.[checkdate] = DS2.[checkdate]
            AND DATEDIFF(HOUR, DS1.[recordout], DS2.[recordout]) < 3
            AND DS1.[recordout] < DS2.[recordout]
    ) DS
)
SELECT DS1.*
FROM @DataSource DS1
LEFT JOIN DataSource DS2
    ON DS1.[checkdate] = DS2.[checkdate]
    AND DS1.[recordout] = DS2.[recordout]
WHERE DS2.[checkdate] IS NULL
ORDER BY DS1.[recordout] ASC;

enter image description here

...