Проверьте, есть ли существующая запись накануне - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь проверить, существует ли существующая запись за день до выбранной даты расписания. как нам это сделать? Я пытался использовать LAG(), но у меня возникают проблемы с сортировкой данных, поскольку NULL.

DATEDIFF() также не решит мою проблему, потому что мне нужно проверить если на эту дату существуют данные, а не -1 на дату.

Что я хочу запросить, если пример. За день до 2020-01-02 имеет запись и запись , при необходимости он должен отражать NULL. Есть ли способ сделать это?

Это будет результат.

scheduledate   schedulein         scheduleout        recordin           recordout          prevrecordin      prevrecordout
2020-01-02     08:00:00.0000000   17:00:00.0000000   07:41:12.0000000   17:16:54.0000000   NULL               NULL

prevrecordin и prevrecordout будут оба NULL, поскольку 2020-01-01 равно NULL .

Это первая таблица.

badgenumber checktype   recordin                    checkdate
10          I           2019-12-20 07:35:58.000     2019-12-20
10          I           2019-12-21 05:18:14.000     2019-12-21
10          I           2019-12-23 07:35:33.000     2019-12-23
10          I           2019-12-26 07:48:20.000     2019-12-26
10          I           2019-12-27 07:41:03.000     2019-12-27
10          I           2019-12-28 07:35:42.000     2019-12-28
10          I           2020-01-02 07:41:12.000     2020-01-02
10          I           2020-01-03 07:50:12.000     2020-01-03
10          I           2020-01-04 07:41:12.000     2020-01-04

Этот запрос обрабатывается этим.

.....
OUTER APPLY (
                    SELECT TOP(1) t1.recordin, t1.badgenumber
                    FROM (SELECT MAX(userinfo.badgenumber) AS badgenumber, MAX(RTRIM(checkinout.checktype)) AS 'checktype', 
                    MIN(checkinout.checktime) as 'recordin', MIN(CONVERT(date,checkinout.checktime)) as checkdate, 
                    MAX(RTRIM(employeemasterfile.employeeidno)) AS 'employeeidno' 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 DATEADD(DAY, -1,'2019-12-21') AND DATEADD(DAY, 1,'2020-01-05') and badgenumber = '10'
                    AND CHECKINOUT.CHECKTYPE = 'I' COLLATE SQL_Latin1_General_CP1_CS_AS GROUP BY userinfo.badgenumber, LEFT(checkinout.checktime,14)) AS t1
                     WHERE 
                        t1.recordin BETWEEN DATEADD(HOUR,-(t0.noofhoursduty),t0.mergetimeinorig) AND DATEADD(HOUR, (t0.noofhoursduty),t0.mergetimeinorig)
                        AND t1.badgenumber = t0.fingerscanno
                        AND t0.schedulename !='REST'
                     ORDER BY abs(datediff(minute, t0.mergetimeinorig, t1.recordin )) DESC

                    ) t1

Это вторая таблица.

badgenumber checktype   recordout               checkdate
10          O           2019-12-20 20:41:46.000 2019-12-20
10          O           2019-12-21 14:12:34.000 2019-12-21
10          O           2019-12-23 17:03:44.000 2019-12-23
10          O           2019-12-26 17:05:16.000 2019-12-26
10          O           2019-12-27 17:02:32.000 2019-12-27
10          O           2019-12-28 17:07:38.000 2019-12-28
10          O           2020-01-02 17:16:54.000 2020-01-02
10          O           2020-01-03 17:05:11.000 2020-01-03
10          O           2020-01-04 17:04:42.000 2020-01-04

Это обрабатывается этим запросом.

OUTER APPLY (
                    SELECT TOP(1) t2.recordout, t2.badgenumber
                    FROM (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' 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 DATEADD(DAY, -1,'2019-12-21') AND DATEADD(DAY, 1,'2020-01-05') and badgenumber = '10'
                    AND CHECKINOUT.CHECKTYPE = 'O' COLLATE SQL_Latin1_General_CP1_CS_AS GROUP BY userinfo.badgenumber, LEFT(checkinout.checktime,14)) AS t2
                     WHERE 
                        t2.recordout BETWEEN DATEADD(HOUR,-(t0.noofhoursduty),t0.mergetimeoutorig) AND DATEADD(HOUR, (t0.noofhoursduty),t0.mergetimeoutorig)
                        AND t2.badgenumber = t0.fingerscanno
                        AND t0.schedulename !='REST'
                     ORDER BY abs(datediff(minute, t0.mergetimeoutorig, t2.recordout )) DESC
                    ) t2

Это результат запроса.

для t1.recordin и t2.recordout, запланированное поступление из t0.scheduledate с соответствующая дата в таблице соответственно.

scheduledate   schedulein         scheduleout        recordin           recordout
2019-12-21     06:00:00.0000000   14:00:00.0000000   05:18:14.0000000   14:12:34.0000000
2019-12-23     08:00:00.0000000   17:00:00.0000000   07:35:33.0000000   17:03:44.0000000
2019-12-24     08:00:00.0000000   17:00:00.0000000   NULL               NULL
2019-12-25     08:00:00.0000000   17:00:00.0000000   NULL               NULL
2019-12-26     08:00:00.0000000   17:00:00.0000000   07:48:20.0000000   17:05:16.0000000
2019-12-27     08:00:00.0000000   17:00:00.0000000   07:41:03.0000000   17:02:32.0000000
2019-12-28     08:00:00.0000000   17:00:00.0000000   07:35:42.0000000   17:07:38.0000000
2019-12-30     08:00:00.0000000   17:00:00.0000000   NULL               NULL
2019-12-31     08:00:00.0000000   17:00:00.0000000   NULL               NULL
2020-01-01     08:00:00.0000000   17:00:00.0000000   NULL               NULL
2020-01-02     08:00:00.0000000   17:00:00.0000000   07:41:12.0000000   17:16:54.0000000
2020-01-03     08:00:00.0000000   17:00:00.0000000   07:50:12.0000000   17:05:11.0000000
2020-01-04     08:00:00.0000000   17:00:00.0000000   07:41:12.0000000   17:04:42.0000000

Я также пытался сделать CASE WHEN (LAG()), к сожалению, я не могу сделать это из-за значения NULL.

Что мне нужно сделать, так это новый столбец, который будет отображать примерно так:

Аналогичный ожидаемый результат.

scheduledate    schedulein  scheduleout recordin    recordout   prevrecordin    prevrecordout
21/12/2019      06:00:00    14:00:00    05:18:14    14:12:34    NULL            NULL
23/12/2019      08:00:00    17:00:00    07:35:33    17:03:44    05:18:14        14:12:34
24/12/2019      08:00:00    17:00:00    NULL        NULL        07:35:33        17:03:44
25/12/2019      08:00:00    17:00:00    NULL        NULL        NULL            NULL
26/12/2019      08:00:00    17:00:00    07:48:20    17:05:16    NULL            NULL
27/12/2019      08:00:00    17:00:00    07:41:03    17:02:32    07:48:20        17:05:16
28/12/2019      08:00:00    17:00:00    07:35:42    17:07:38    07:41:03        17:02:32
30/12/2019      08:00:00    17:00:00    NULL        NULL        07:35:42        17:07:38
31/12/2019      08:00:00    17:00:00    NULL        NULL        NULL            NULL
01/01/2020      08:00:00    17:00:00    NULL        NULL        NULL            NULL
02/01/2020      08:00:00    17:00:00    07:41:12    17:16:54    NULL            NULL
03/01/2020      08:00:00    17:00:00    07:50:12    17:05:11    07:41:12        17:16:54
04/01/2020      08:00:00    17:00:00    07:41:12    17:04:42    07:50:12        17:05:11

Ваша помощь будет принята с благодарностью. Спасибо.

1 Ответ

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

Исходя из ваших выборочных данных, я предполагаю следующее:

  • Максимум записей на значок в день.
  • recordin и recordout в один и тот же день.
  • checktype не имеет значения
  • Вы знаете, как генерировать данные в исходной таблице.

Если это так, вы можете использовать lag():

select t.*,
       (case when datediff(day,
                           lag(recordin) over (partition by badgenumber order by recordin),
                           recordin
                          ) <> 1
             then null
             else lag(recordin) over (partition by badgenumber order by recordin)
       end),
       (case when datediff(day,
                           lag(recordin) over (partition by badgenumber order by recordin),
                           recordin
                          ) <> 1
             then null
             else lag(recordout) over (partition by badgenumber order by recordin)
       end),
from t;

Если вышеприведенное неверно, я бы предложил вам задать новый вопрос. Попробуйте упростить проблему. Ваш довольно сложный запрос не имеет ничего общего с вопросом, который вы задаете, поэтому он не помогает в этом вопросе.

...