力扣2292-连续两年有3个及以上的订单产品

https://leetcode.cn/problems/products-with-three-or-more-orders-in-two-consecutive-years/description/

表: 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
;
相关推荐
Filotimo_12 小时前
N+1查询问题
数据库·oracle
June`14 小时前
全排列与子集算法精解
算法·leetcode·深度优先
夏鹏今天学习了吗15 小时前
【LeetCode热题100(78/100)】爬楼梯
算法·leetcode·职场和发展
圣保罗的大教堂15 小时前
leetcode 712. 两个字符串的最小ASCII删除和 中等
leetcode
岁岁种桃花儿17 小时前
MySQL 8.0 基本数据类型全面解析
数据库·mysql·数据库开发
有一个好名字18 小时前
力扣-确定两个字符串是否接近
算法·leetcode·职场和发展
独自破碎E19 小时前
【层序遍历】序列化二叉树
leetcode
菜鸟233号19 小时前
力扣518 零钱兑换II java实现
java·数据结构·算法·leetcode·动态规划
VT.馒头21 小时前
【力扣】2622. 有时间限制的缓存
javascript·算法·leetcode·缓存·typescript
程序修理员21 小时前
oracle备份表还原
数据库·oracle