Можно ли это сделать как SQL ПРОСМОТР - PullRequest
0 голосов
/ 05 августа 2020

У меня есть SQL Серверная таблица событий клиента:

CREATE TABLE CustomerEvent
(
    CustomerID int,
    EventType int,
    EventDate datetime
)

За один день может быть много типов событий для одного и того же клиента.

Типы событий похожи на

1 - CheckIn 2 - Отъезд 3 - ExamStart 4 - ExamEnd

Теперь я хочу выбрать клиентов, которые в настоящее время (сегодня) находятся в помещении. Это клиенты, которые зарегистрировались, но не выехали, независимо от того, сдают они экзамен в настоящее время или нет. Можно ли это сделать как представление SQL, или мне нужно написать для этого хранимую процедуру?

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

Хочешь сегодня. Поэтому я бы предложил not exists:

select ce.customerid
from customerevent ce
where eventtype = 1 and
      event_date >= current_date and
      event_date < current_date + interval '1 day' and
      not exists (select 1
                  from customerevent ce2
                  where ce2.customerid = ce.customerid and
                        ce2.eventtype = 2 and
                        ce2.eventdate > ce.eventdate
                 );

Вы можете легко включить это в представление.

Примечание: функции даты / времени, как известно, специфичны для базы данных c, поэтому точный синтаксис «сегодня» может отличаться.

РЕДАКТИРОВАТЬ:

На SQL сервере это может быть записано как:

select ce.customerid
from customerevent ce
where eventtype = 1 and
      convert(date, event_date) >= concat(date, current_date) and
      not exists (select 1
                  from customerevent ce2
                  where ce2.customerid = ce.customerid and
                        ce2.eventtype = 2 and
                        ce2.eventdate > ce.eventdate
                 );
2 голосов
/ 05 августа 2020

Вы можете использовать агрегирование и фильтр с предложением having, которое сравнивает последнюю регистрацию каждого клиента с последней проверкой:

create view customerview as
select customerid
from customerevent
group by customerid
having 
    max(case when eventtype = 1 then eventdate end) 
        > max(case when eventtype = 2 then eventdate end)
    or (
        max(case when eventtype = 1 then eventdate end) is not null
        and max(case when eventtype = 2 then eventdate end) is null
    )

Второе условие в условии having обрабатывает клиенты, которые зарегистрировались хотя бы один раз, но никогда не выезжали.

Мы можем немного упростить запрос с помощью coalesce() и фиксированной даты, которая обязательно должна быть перед любой строкой в ​​вашей таблице:

having max(case when eventtype = 1 then eventdate end) 
    > max(case when eventtype = 2 then eventdate else '19700101' end)
...