表: Orders
+---------------+------+
| Column Name | Type |
+---------------+------+
| order_id | int |
| product_id | int |
| quantity | int |
| purchase_date | date |
+---------------+------+
order_id 包含唯一值。
该表中的每一行都包含订单 ID、购买的产品 ID、数量和购买日期。
编写解决方案,获取连续两年订购三次或三次以上的所有产品的 id。
以 任意顺序返回结果表。
结果格式示例如下。
示例 1:
输入:
Orders 表:
+----------+------------+----------+---------------+
| order_id | product_id | quantity | purchase_date |
+----------+------------+----------+---------------+
| 1 | 1 | 7 | 2020-03-16 |
| 2 | 1 | 4 | 2020-12-02 |
| 3 | 1 | 7 | 2020-05-10 |
| 4 | 1 | 6 | 2021-12-23 |
| 5 | 1 | 5 | 2021-05-21 |
| 6 | 1 | 6 | 2021-10-11 |
| 7 | 2 | 6 | 2022-10-11 |
+----------+------------+----------+---------------+
输出:
+------------+
| product_id |
+------------+
| 1 |
+------------+
解释:
产品 1 在 2020 年和 2021 年都分别订购了三次。由于连续两年订购了三次,所以我们将其包含在答案中。
产品 2 在 2022 年订购了一次。我们不把它包括在答案中。
思路:
1、首先截取order_date的年,对product_id和年分组,count统计个数,然后根据执行顺序用having count(1) >= 3 ,这一步是求出哪些产品在这一年是被订购了三次及以上;
2、然后用CTE,对上面的结果进行row_number排序,然后用年year -row_number 得出差值;
原理:
原理:
-
假设一个产品的年份是 2020, 2021, 2022
-
row_number(简称rn) = 1, 2, 3
-
year - rn= 2019, 2019, 2019 → 相同的 diff → 同一个连续年份组
如果年份断了,比如 2020, 2022
-
rn= 1, 2 -
year - rn= 2019, 2020 → 不同 grp_id → 被划分成不同组
所以 diff年份段聚在一起了。
3、根据product_id和diff分组,having count(1)>=2 是筛选连续的年,因为连续最少就是两年就是连续,最后 对product_id去重得出结果。
代码:
sql
with t as(
select
product_id,
extract(year from purchase_date) as year,
count(1)
from orders
group by product_id,extract(year from purchase_date)
having count(1) >=3
)
,t1 as(
select
product_id,
year,
year - row_number() over(partition by product_id order by year) diff
from t
)
select distinct product_id from t1 group by product_id,diff
having count(*) >= 2
;