这可以作为 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
);
我有一个 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
);