这可以作为 SQL VIEW 来完成吗

Can this be done as a SQL VIEW

我有一个 SQL 服务器 table 的客户事件:

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

同一客户一天内可以有多个事件类型。

事件类型类似于

1 - 签到
2 - 签出
3 - 考试开始
4 - 考试结束

现在我想 select 当前(今天)在现场的客户。那是已经签到但还没有签出的客户,无论他们目前是否参加考试。这可以作为 SQL 视图来完成,还是我必须为此编写一个存储过程?

您可以使用聚合,并使用 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() 和一个固定日期来稍微简化查询,您确定该日期位于 table 中任何行之前:

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

你今天要。所以我建议 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
                 );

您可以轻松地将其合并到视图中。

注意:date/time众所周知,函数是特定于数据库的,因此“今天”的确切语法可能会有所不同。

编辑:

在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
                 );