У меня есть многократный статус входа и выхода человека. как получить последний статус одного человека - PullRequest
0 голосов
/ 16 января 2020

У меня есть таблица в sql в следующем формате

Userid  Status  Logtime
1         In    10:10
1         In    10:12
2         In    10:14
3         In    10:16
3         Out   10:18
1         Out   10:20
4         In    10:22
2         Out   10:24

Требуется вывод

Userid  Status  In_time Out_time
1         out            10:20
2         In    10:14    10:24
3         In    10:16    10:18
4         In    10:22   

Ответы [ 2 ]

2 голосов
/ 16 января 2020

Вы можете попробовать это.

Create table TblInOut(Userid int, sStatus Varchar(10),  Logtime Varchar(10))
insert into TblInOut Values(1, 'In', '10:10'), (1, 'In', '10:12'), (2, 'In', '10:14'), (3, 'In', '10:16'), (3, 'Out', '10:18'),
(1, 'Out', '10:20'), (4, 'In', '10:22'), (2, 'Out', '10:24')

select Userid, 
       max(case when sStatus = 'In' then Logtime end) as INTIME,
       max(case when sStatus = 'Out' then Logtime end) as OUTIME
from (select t.*, 
             row_number () over (order by Cast(Logtime as Time)) as seq1,
             row_number () over (partition by Userid order by Cast(Logtime as Time)) as seq2
      from TblInOut t
     ) t
group by Userid;

Это выдаст, как показано ниже. Вот демоверсия , заданная .

Userid  INTIME  OUTIME
----------------------
1       10:12   10:20
2       10:14   10:24
3       10:16   10:18
4       10:22   NULL

Редактировать

Чтобы проверить указанный период c, вы можете использовать следующий запрос , Если вы хотите проверить пользователя и общее количество только для вывода, измените статус имеющего предложения на Out.

select Userid, 
       max(case when sStatus = 'In' then Logtime end) as INTIME,
       max(case when sStatus = 'Out' then Logtime end) as OUTIME,
       Count(*) as TotalInOut
from TblInOut t
group by Userid having max(case when sStatus = 'In' then Logtime end) between Cast('10:10' as Time) and Cast('10:18' as Time);

Если вы хотите, чтобы человек сделал in, а также out для уточнения. c period, тогда вы можете использовать пункт using, как показано ниже.

having max(case when sStatus = 'In' then Logtime end) between Cast('10:10' as Time) and Cast('10:18' as Time)
    and max(case when sStatus = 'Out' then Logtime end) between Cast('10:10' as Time) and Cast('10:18' as Time);

Вы также можете использовать оператор OR, чтобы проверять вход или выход в течение указанного c периода времени в вышеуказанном предложении.

Вы можете использовать Min () для входа, как предложено, и Max () для выхода. Чтобы объединить запрос с другими таблицами, вы можете следовать этому demo

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

In_Time должен быть первым вместо последнего статуса.

Тогда ваш результат должен быть вместо

Userid IN_TIME OUT_TIME

1       10:10   10:20
2       10:14   10:24
3       10:16   10:18
4       10:22   NULL

Код, как показано ниже, демоверсия здесь

SELECT Userid,
MIN(CASE WHEN sStatus = 'IN' THEN Logtime ELSE NULL END) AS IN_TIME, 
MAX(CASE WHEN sStatus = 'Out' THEN Logtime ELSE NULL END) OUT_TIME
FROM TblInOut
GROUP BY Userid

Обновлено

Если вы хотите получить последний статус для In_Time, просто слегка отрегулируйте условие с Min до Max, как показано ниже, живая демонстрация здесь

SELECT Userid,
       MAX(CASE WHEN sStatus = 'IN' THEN Logtime ELSE NULL END) AS IN_TIME, 
       MAX(CASE WHEN sStatus = 'Out' THEN Logtime ELSE NULL END) OUT_TIME
FROM TblInOut
GROUP BY Userid

Выход

Userid  IN_TIME OUT_TIME
1       10:12   10:20
2       10:14   10:24
3       10:16   10:18
4       10:22   NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...