Рассчитать своевременную посещаемость в месяц - PullRequest
0 голосов
/ 29 апреля 2020

Я хочу рассчитать количество пришедших вовремя или рано работника на указанную c дату. Но в примере я указал c USERID в качестве дополнительных критериев.

Это моя таблица CHECKINOUT (всего 39 строк):

USERID      CHECKTIME       CHECKTYPE   VERIFYCODE  SENSORID    WorkCode        sn          UserExtFmt      Update          
1040    02/03/2020 6:54:50      I           1           3           0       0840060140610       0       02/03/2020 10:13:56 
1040    02/03/2020 8:00:00      I           1           2           0       0840060140160       0       02/03/2020 10:50:20 
1040    02/03/2020 16:34:37     I           1           5           0       2809731360643       0       26/03/2020 9:51:41  
1040    03/03/2020 8:02:41      I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    03/03/2020 16:45:00     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    03/03/2020 16:45:03     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    04/03/2020 7:57:46      I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    04/03/2020 7:57:48      I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    04/03/2020 17:01:53     I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    04/03/2020 17:01:56     I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    05/03/2020 8:03:45      I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    05/03/2020 8:03:48      I           1           2           0       0840060140160       0       26/03/2020 9:50:49  
1040    05/03/2020 16:41:02     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    05/03/2020 16:41:05     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    06/03/2020 8:27:13      I           1           2           0       0840060140160       0       26/03/2020 9:50:50  
1040    06/03/2020 17:26:03     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    06/03/2020 17:26:06     I           1           5           0       2809731360643       0       26/03/2020 9:51:42  
1040    07/03/2020 11:53:57     I           1           2           0       0840060140160       0       26/03/2020 9:50:50  
1040    09/03/2020 8:01:51      I           1           2           0       0840060140160       0       27/03/2020 10:29:16 
1040    16/03/2020 7:58:20      I           1           2           0       0840060140160       0       26/03/2020 9:50:52  
1040    16/03/2020 7:58:22      I           1           2           0       0840060140160       0       26/03/2020 9:50:52  
1040    16/03/2020 16:34:07     I           1           5           0       2809731360643       0       26/03/2020 9:51:43  
1040    17/03/2020 7:59:05      I           1           2           0       0840060140160       0       26/03/2020 9:50:52  
1040    17/03/2020 16:43:50     0           1           5           0       2809731360643       0       26/03/2020 9:51:44  
1040    18/03/2020 8:00:43      I           1           5           0       2809731360643       0       26/03/2020 9:51:44  
1040    18/03/2020 8:00:46      I           1           5           0       2809731360643       0       26/03/2020 9:51:44  
1040    18/03/2020 16:30:23     I           1           2           0       0840060140160       0       26/03/2020 9:50:52  
1040    19/03/2020 8:03:24      I           1           2           0       0840060140160       0       26/03/2020 9:50:53  
1040    19/03/2020 17:13:44     I           1           2           0       0840060140160       0       26/03/2020 9:50:54  
1040    20/03/2020 8:10:41      I           1           3           0       0840060140610       0       26/03/2020 9:51:10  
1040    20/03/2020 8:10:44      I           1           3           0       0840060140610       0       26/03/2020 9:51:10  
1040    20/03/2020 17:01:41     I           1           5           0       2809731360643       0       26/03/2020 9:51:44  
1040    23/03/2020 8:00:07      I           1           2           0       0840060140160       0       26/03/2020 9:50:54  
1040    23/03/2020 16:38:09     I           1           5           0       2809731360643       0       26/03/2020 9:51:45  
1040    24/03/2020 7:59:08      I           1           5           0       2809731360643       0       26/03/2020 9:51:45  
1040    24/03/2020 7:59:11      I           1           5           0       2809731360643       0       26/03/2020 9:51:45  
1040    24/03/2020 16:39:30     I           1           2           0       0840060140160       0       26/03/2020 9:50:55  
1040    24/03/2020 16:39:33     I           1           2           0       0840060140160       0       26/03/2020 9:50:55  
1040    26/03/2020 8:10:31      I           1           3           0       0840060140610       0       26/03/2020 9:51:11      

Это мой CHECKEXACT выглядит так:

EXACTID     USERID      CHECKTIME   
404         1040    09/03/2020 8:01:51

Я пытался добиться этого с помощью SUM агрегатной функции и условия IIf, но, к сожалению, запрос дал мне неверный результат.

Это мой запрос:

SELECT af.USERID, SUM(
        IIf(af.CHECKTIME Is Not Null,
            IIf(WeekDay(DateValue(af.CHECKTIME)) <> 6 And Format(af.CHECKTIME, 'hh:nn:ss') <= '08:15:00', 
                1, IIf(Format(af.CHECKTIME, 'hh:nn:ss') <= '08:30:00', 1, 0)
            ),
            IIf(bf.CHECKTIME Is Not Null,
                IIf(WeekDay(DateValue(bf.CHECKTIME)) <> 6 And Format(bf.CHECKTIME, 'hh:nn:ss') <= '08:15:00', 
                    1, IIf(Format(bf.CHECKTIME, 'hh:nn:ss') <= '08:30:00', 1, 0)
                ), 0
            )
        )
    ) AS [Came On Time or Early]  
FROM (CHECKINOUT AS af
    LEFT JOIN CHECKEXACT bf ON  af.USERID = bf.USERID)
    WHERE af.USERID = 1040 And af.CHECKTIME Between #3/1/2020# And #3/31/2020#  GROUP BY af.USERID

Вышеупомянутый запрос возвращает этот результат:

USERID  Came On Time or Early
1040            441

Как мы знаем, если бы мы COUNT CHECKINOUT таблица, она вернула бы 39 строк, а CHECKEXACT вернет только 1 строку. Но запрос возвращает 441 как [Пришло вовремя или рано].

Я не знаю, что не так с моим запросом, я думаю, что поставил правильный запрос, чтобы получить общее количество пришедших вовремя или рано сотрудник с USERID = 1040 на март 2020 года.

Не могли бы вы сказать, что не так с моим запросом?

1 Ответ

0 голосов
/ 05 мая 2020

Спасибо @ June7 за ответ на этот вопрос через комментарий.

После многократной проверки я понял, что написал неправильный запрос, особенно в этой строке:

IIf(WeekDay(DateValue(af.CHECKTIME)) <> 6 And Format(af.CHECKTIME, 'hh:nn:ss') <= '08:30:00', 
                1, IIf(Format(af.CHECKTIME, 'hh:nn:ss') <= '08:30:00', 1, 0)
            )

Я должен отделиться ...WeekDay(DateValue(af.CHECKTIME)) <> 6... в другую часть. Мой предыдущий запрос будет считать пятницу не пятницей, если время af.CHECKTIME больше '08: 30: 00', а день - пятница. И тогда я прыгнул бы к IIf в ложной части, где я предполагаю работать в другой будний день.

А также я должен изменить эту строку:

...
FROM (CHECKINOUT AS af
    LEFT JOIN CHECKEXACT bf ON  af.USERID = bf.USERID)
...

На это:

...
FROM(
    SELECT af.USERID, MIN(af.CHECKTIME) AS [Tanggal dan Waktu]
        FROM CHECKINOUT AS af
    WHERE af.USERID = 1040 And af.CHECKTIME Between #3/1/2020# And #3/31/2020#
    GROUP BY af.USERID, DateValue(af.CHECKTIME) 
        UNION
    SELECT bf.USERID, MIN(bf.CHECKTIME) AS [Tanggal dan Waktu]
        FROM CHECKEXACT AS bf
    WHERE bf.USERID = 1040 And bf.CHECKTIME Between #3/1/2020# And #3/31/2020#
    GROUP BY bf.USERID, DateValue(bf.CHECKTIME) 
)
...

Поскольку в предыдущем запросе From напечатал бы всю дату / время между заданным диапазоном, а LEFT JOIN CHECKEXACT напечатал бы данные CHECKEXACT, что только строка (09/03/2020 8:01:51 каждая проверка будет истинной, потому что меньше '08:30:00' и, конечно, будет печатать 1) многократно столько строк, сколько CHECKINOUT, в то время как мне нужно только проверять наличие присутствия, которое является только минимальной датой-временем каждого дня как CHECKINOUT, так и CHECKEXACT.

Так что правильный полный запрос будет выглядеть так:

SELECT USERID, 
    SUM(IIf(WeekDay(DateValue([Tanggal dan Waktu])) <> 6,
            IIf(TimeValue([Tanggal dan Waktu]) <= TimeValue('08:30:00'), 
                1, 0
            ),                                      
            IIf(TimeValue([Tanggal dan Waktu]) <= TimeValue('08:30:00'), 1, 0)
        )
    )
    AS [Came On Time or Early]
FROM(
    SELECT af.USERID, MIN(af.CHECKTIME) AS [Tanggal dan Waktu]
        FROM CHECKINOUT AS af
    WHERE af.USERID = 1040 And af.CHECKTIME Between #3/1/2020# And #3/31/2020#
    GROUP BY af.USERID, DateValue(af.CHECKTIME) 
        UNION
    SELECT bf.USERID, MIN(bf.CHECKTIME) AS [Tanggal dan Waktu]
        FROM CHECKEXACT AS bf
    WHERE bf.USERID = 1040 And bf.CHECKTIME Between #3/1/2020# And #3/31/2020#
    GROUP BY bf.USERID, DateValue(bf.CHECKTIME) 
)
GROUP BY USERID

Приведенный выше запрос выведет 6 как правильную / желаемую [Came On Time or Early] запись.

...