【MySQL】巧用 Dense_Rank 窗口函数

力扣题

1、题目地址

2084. 为订单类型为 0 的客户删除类型为 1 的订单

2、模拟表

活动表:Orders

Column Name Type
order_id int
customer_id int
order_type int
  • order_id是此表的主键列。
  • 此表的每一行都表示订单的ID、订购该订单的客户的ID以及订单类型。
  • 订单可以是类型0或类型1。

3、要求

编写SQL查询以根据以下条件报告所有订单:

如果客户至少有一个类型为0的订单,则不要报告该客户的任何类型为1的订单。

否则,报告客户的所有订单。

按任意顺序返回结果表。

查询结果格式如下例所示。

示例 1:

输入:
Orders 表:

order_id customer_id order_type
1 1 0
2 1 0
11 2 0
12 2 1
21 3 1
22 3 0
31 4 1
32 4 1

输出:

order_id customer_id order_type
31 4 1
32 4 1
1 1 0
2 1 0
11 2 0
22 3 0

解释:

客户1有两个类型为0的订单。我们两个都返回。

客户2的订单类型为0,订单类型为1。我们只返回类型为0的订单。

客户3的订单类型为0,订单类型为1。我们只返回类型为0的订单。

客户4有两个类型1的订单。我们两个都返回。

4、代码编写

代码思路

1、客户订单类型不存在为 0 则返回全部(包括 0 和 1)

2、客户订单类型存在为 0 返回 0

我的代码

sql 复制代码
SELECT *
FROM Orders a
WHERE NOT EXISTS(SELECT * FROM Orders WHERE customer_id = a.customer_id AND order_type = '0')
UNION ALL
SELECT *
FROM Orders a
WHERE EXISTS(SELECT * FROM Orders WHERE customer_id = a.customer_id AND order_type = '0')
AND order_type = '0'

网友代码(巧用 Dense_Rank 窗口函数)

专用窗口函数:rank,dense_rank,row_number

Rank:有相同名次,名次按实际个数走,会跳数字

Dense_rank: 有相同名次,名次不跳数

Row_number:相同分数按行数排序

分数 Rank Dense_Rank Row_number
100 1 1 1
100 1 1 2
90 3 2 3
sql 复制代码
SELECT order_id, customer_id, order_type
FROM (
    SELECT *,
           Dense_Rank() over (partition by customer_id order by order_type) rk
    FROM Orders
) AS a
WHERE rk = 1

逻辑:对不同 customer_id 进行分组处理,每个组里面根据 order_type 进行排序,所以有 0 的话肯定是排在前面的,使用的是 Dense_Rank 窗口函数,这意味着如果 order_type 相同的话,数字是不会增加的,所以如果有 order_type 有存在等于 0 的话,就返回对应 rk = 1 (返回 0)就行,如果 order_type 不存在等于 0 的话,也就是返回全部 rk = 1(返回 1,因为没有 0 的),只能说用得很巧妙

Rank 窗口函数也是可以的

sql 复制代码
SELECT order_id, customer_id, order_type
FROM (
    SELECT *,
           Rank() over (partition by customer_id order by order_type) rk
    FROM Orders
) AS a
WHERE rk = 1

Dense_Rank 和 Rank 窗口函数可参考

MYSQL窗口函数(Rows & Range)------ 滑动窗口函数用法

相关推荐
Lx3522 小时前
排序缓冲区调优:sort_buffer_size的合理配置
sql·mysql·性能优化
feifeigo1239 天前
Java 正则表达式高级用法
java·mysql·正则表达式
敏叔V5879 天前
大模型Text2SQL之在CentOS上使用yum安装与使用MySQL
linux·mysql·centos
程序猿小D9 天前
[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+Vue实现的校园二手交易平台管理系统,推荐!
java·数据库·mysql·spring·vue·毕业设计·校园二手交易平台
张太行_9 天前
MySQL与Excel比较
数据库·mysql·excel
斯普信专业组9 天前
MySQL 8.x配置MGR高可用+ProxySQL读写分离(二):ProxySQL配置MySQL代理及读写分离
数据库·mysql
中国lanwp9 天前
InnoDB Cluster 与 NDB Cluster 对比及部署指南
mysql
亲爱的非洲野猪9 天前
MySQL 事务实现机制详解
数据库·mysql
程序员岳焱9 天前
Java 与 MySQL 性能优化:MySQL性能指标解读与监控方法
后端·mysql·性能优化
i小溪9 天前
着重介绍一下sql语句中的JSON_UNQUOTE、JSON_EXTRACT
数据库·mysql