sql - 从客户事件、SQL 中查找放弃的搜索

标签 sql postgresql join where-clause

在交易平台中,用户有三种不同的操作:LOGIN , SEARCH , ORDER .

被遗弃SEARCH操作定义为:客户LOGIN然后做一些SEARCH并且不要ORDER之前 下一个 LOGIN 。 现在我有一张 table :action_table ,录音customer_id , action , request_time .

我想知道如何通过 SQL 查找所有废弃的 SEARCH 操作?


更新: 这是一个简短的示例:

CREATE TABLE action_table(
   customer_id  VARCHAR(1) NOT NULL
  ,action       VARCHAR(6) NOT NULL
  ,request_time DATE  NOT NULL
);
INSERT INTO action_table(customer_id,action,request_time) 
VALUES 
('A','LOGIN','2023-05-01'),
('A','SEARCH','2023-05-02'),
('A','SEARCH','2023-05-03'),
('A','ORDER','2023-05-04'),
('B','LOGIN','2023-05-01'),
('B','SEARCH','2023-05-02'),
('B','SEARCH','2023-05-03'),
('B','LOGIN','2023-05-04'),
('B','SEARCH','2023-05-05')
<表类=“s-表”> <标题> customer_id Action 请求时间 <正文> 一个 登录 2023-05-01 一个 搜索 2023-05-02 一个 搜索 2023-05-03 一个 订单 2023-05-04 B 登录 2023-05-01 B 搜索 2023-05-02 B 搜索 2023-05-03 B 登录 2023-05-04 B 搜索 2023-05-05

在本例中,NO 放弃了对 A 的搜索,3 放弃了对 B 的搜索。

这是我的代码:

select customer_id, count(1)
from action_table c1
left join 
(
  select customer_id, action, request_time 
  from action_table
  where action = 'LOGIN'
) c2
  on c1.customer_id = c2.customer_id
  and c2.request_time > c1.request_time
left join 
(
  select customer_id, action, request_time 
  from action_table
  where action = 'ORDER'
) c3
  on c1.customer_id = c3.customer_id
  and c3.request_time > c1.request_time
  and c3.request_time < c2.request_time
where c1.action = 'SEARCH'
  and c2.customer_id IS NOT NULL
  and c3.customer_id IS NULL
group by 1

这是多余的,而且似乎效果不佳:(

最佳答案

一个选项使用LEAD;这个想法是检查每个登录事件的以下两个操作以识别放弃的搜索:

select customer_id, count(*) cnt_abandonned_search
from (
    select a.*, 
        lead(action, 1) over(partition by customer_id order by request_time) lead_action_1,
        lead(action, 2) over(partition by customer_id order by request_time) lead_action_2
    from action_table a
) a
where action = 'LOGIN'                         -- a LOGIN action...
  and lead_action_1 = 'SEARCH'                 -- ... followed by a SEARCH
  and lead_action_2 is distinct from 'ORDER'   -- ... but not followed by an ORDER
group by customer_id

如果您想专注于搜索,并获取每个放弃搜索的完整记录,我们可以使用相同的逻辑,但使用 leadlag:

select *
from (
    select a.*, 
        lag (action) over(partition by customer_id order by request_time) lag_action,
        lead(action) over(partition by customer_id order by request_time) lead_action
    from action_table a
) a
where action = 'SEARCH'                    -- a SEARCH action...
  and lag_action = 'LOGIN'                 -- ... preceded by a LOGIN
  and lead_action is distinct from 'ORDER' -- ... but not followed by an ORDER

<强> Demo on DB Fiddle

关于sql - 从客户事件、SQL 中查找放弃的搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76388701/

相关文章:

mysql - 使用单个 mysql 查询为用户获取组(仅允许)

mysql - 在 mysql 中连接两个表时出现错误,如 "Unknown column ' m.machinenumber' in 'on clause' "?

mysql - 比较两个表的数据,将共同数据存储在第三个表中,否则存储在第四个表中

sql - 甲骨文分析窗口

javascript - 使用 Node js 连接到 postgres

Postgresql COPY 命令 - 如何删除临时文件?

sql - Postgres : full join on two fields (data gap issue)

mysql - 我想将函数的 NOT NULL 字符串结果与表中可以为 NULL 的字段组合起来

如果一列为Null,则SQL返回Null(与COALESCE()相反)

sql - 如果序列未被破坏,则从多行获取总时间间隔