检查连续多次经历相同状态的记录
Posted
技术标签:
【中文标题】检查连续多次经历相同状态的记录【英文标题】:Check records that have gone through the same status more than once in a row 【发布时间】:2020-11-12 19:44:16 【问题描述】:我有一个状态历史表,我需要知道哪个 id_user 依次通过了相同的状态。
表结构
create table user (
id_user number,
user_name number,
status_name char(1),
created_at timestamp,
primary key (id_user)
);
create table user_status_hist (
id_user_status_hist number,
id_user number,
status_name char(1),
updated_at timestamp,
primary key (id_user),
constraint fk foreign key (id_user) references user(id_user)
);
假设在下面的示例中,对于用户 123,它已连续 2 次通过状态 B。 我怎样才能在我的表中找到所有这样的案例?
select id_user, status_name, updated_at
from user_status_history
where id_user = 123;
--------+-------------+------------+
id_user | status_name | updated_at |
--------+-------------+------------+
123 | A | 2020-11-01 |
--------+-------------+------------+
123 | B | 2020-11-02 |
--------+-------------+------------+
123 | B | 2020-11-05 |
--------+-------------+------------+
通过此查询,我发现我有一个用户多次通过同一状态的情况,但考虑到 updated_at 列,我看不出是否是连续的。
select count(*), idt_card
from user_status_hist
group by id_user, status_name
having count(*) > 1;
我怎样才能得到下面这样的输出? (“计数”列将是他按顺序经历这些状态的次数)
--------+-------------+------------+
id_user | status_name | count |
--------+-------------+------------+
123 | A | 3 |
--------+-------------+------------+
456 | B | 2 |
--------+-------------+------------+
789 | B | 6 |
--------+-------------+------------+
【问题讨论】:
您也许可以使用match_recognize 做某事,但我并没有完全理解您在示例中是如何获得计数的。 【参考方案1】:使用 LAG() 分析函数。由于您必须在比较中使用它,并且只能在 SELECT 子句中计算分析函数(该子句在应用了所有过滤器之后),因此您必须在子查询中计算分析函数并引用它在外部查询中。
select id_user, status_name, updated_at
from (
select id_user, status_name, updated_at,
lag(status_name) over (partition by id_user order by updated_at)
as prev_status
from user_status_hist
)
where status_name = prev_status
;
这将为您提供所有事件的完整详细信息。如果您想按 id_user 和 status_name 和 count 进行分组,您已经知道该怎么做。 (可以直接在上图方案的外层查询中进行。)
【讨论】:
【参考方案2】:您只需要在select
中包含您想要的列:
select idt_card, status_name, count(*)
from user_status_hist
group by id_user, status_name
having count(*) > 1;
【讨论】:
谢谢,但这不会解决“sequentialy”问题。我只需要返回顺序通过相同状态的用户,就像我放的例子一样。以上是关于检查连续多次经历相同状态的记录的主要内容,如果未能解决你的问题,请参考以下文章