【发布时间】:2022-07-30 21:36:33
【问题描述】:
假设我们在一个表中有一个电子商店和所有用户的活动。
events 表如下所示:
| id | user_id | type | time | comment |
|---|---|---|---|---|
| 1 | 1 | visit_site | 2022-04-07 14:08 | |
| 1 | 1 | add_item_to_cart | 2022-04-07 14:17 | |
| 1 | 1 | add_item_to_cart | 2022-04-07 14:17 | |
| 1 | 1 | checkout | 2022-04-07 14:22 | |
| 1 | 1 | pay | 2022-04-07 14:25 | |
| 1 | 2 | visit_site | 2022-04-07 14:30 | |
| 1 | 2 | add_item_to_cart | 2022-04-07 14:40 | |
| 1 | 2 | add_item_to_cart | 2022-04-07 14:44 | |
| 1 | 2 | checkout | 2022-04-07 14:47 | |
| 1 | 2 | pay | 2022-04-07 14:50 |
所以有多种事件类型,它们有时间戳(当它发生时)和作为参与者的用户。
假设我想查找所有将商品添加到购物车并在第二天购买的用户。 我会假设 SQL 查询应该是
SELECT DISTINCT
user_id
FROM
user_event
WHERE
(type = 'add_item_to_cart' AND time BETWEEEN '2022-04-07 00:00' AND '2022-04-08 00:00') AND
(type = 'buy' AND time BETWEEEN '2022-04-08 00:00' AND '2022-04-09 00:00')
现在,我明白了上面的条件基本上等于:
WHERE
type = 'add_item_to_cart' AND time BETWEEEN '2022-04-07 00:00' AND '2022-04-08 00:00' AND
type = 'buy' AND time BETWEEEN '2022-04-08 00:00' AND '2022-04-09 00:00'
这将始终返回空结果,因为我们将两个条件应用于日期范围不相交的 time 列。
所以我有 3 个问题
- 如何重写查询,以便获得在 1 个日期范围内将商品添加到购物车并在另一个日期范围内购买的客户?
- 上述条件实际上与添加到购物车后近 2 天的购买相匹配,即“2022-04-07 00:01” - 添加到购物车,“2022-04-08 23:58” - 已购买。如何制定与前一个条件相关的条件,即从最后结账日期起严格小于 1 天匹配购买(具有匹配的用户 ID)?
- 有没有办法强制事件与同一用户相关,以便查询不会返回在其他人(使用不同的
user_id)将商品添加到购物车后
【问题讨论】:
-
我删除了冲突的 DBMS 标签。请为您真正使用的数据库产品添加一个标签。
-
DISTINCT不是函数,它是一个集合量词,是SELECT DISTINCT的一部分。跳过那些多余的括号,直接写SELECT DISTINCT user_id FROM...,让代码更清晰——适合所有人。 -
您可以在您的事件表中添加一个新的字段(例如 ref_order_id),它可以对相同的事件进行分组。然后您可以根据
pay操作轻松获得所需的结果。
标签: sql