MySQL 窗口函数之ROW_NUMBER

在 MySQL 中,ROW_NUMBER() OVER (PARTITION BY num ORDER BY id)是一个窗口函数的用法

一、ROW_NUMBER()函数

ROW_NUMBER()函数用于为结果集的每一行分配一个唯一的连续整数序号。它从 1 开始,按照指定的顺序依次递增。

二、OVER子句

  1. PARTITION BY子句

    • PARTITION BY用于将结果集划分为多个分区。在这个例子中,按照num列的值进行分区。这意味着具有相同num值的行将被划分到同一个分区中。
    • 例如,如果有一个表包含idnum和其他列,并且有一些行具有相同的num值,那么这些行将在同一个分区内进行编号。
  2. ORDER BY子句

    • ORDER BY用于确定在每个分区内为行分配序号的顺序。在这个例子中,按照id列的值进行升序排序。这意味着在每个分区内,行将根据id列的值从小到大进行编号。

三、整体解释

ROW_NUMBER() OVER (PARTITION BY num ORDER BY id)将为每个分区(由相同的num值确定)内的行按照id列的升序顺序分配一个连续的序号。

例如,假设有以下数据:

idnumother_column
110value1
210value2
320value3
420value4
530value5

执行上述查询后,结果可能如下:

idnumother_columnrow_number
110value11
210value22
320value31
420value42
530value51

在这个结果中,对于num值为 10 的分区,行按照id升序排序,分别被分配了序号 1 和 2。对于num值为 20 的分区,行也按照id升序排序,被分配了序号 1 和 2。对于num值为 30 的分区,只有一行,被分配了序号 1。

适用于 :连续登录问题等

相关题目可参考 力扣 高频sql50题 180 连续出现的数字

### 使用 `ROW_NUMBER()` 窗口函数 `ROW_NUMBER()` 是一种窗口函数,在 MySQL 中用于为查询结果集中每一行分配一个唯一的序号。此功能特别适用于需要对数据进行排序和分组的情况。 #### 基本语法结构 基本的 `ROW_NUMBER()` 语句通常如下所示: ```sql ROW_NUMBER() OVER ( PARTITION BY column_name -- 可选,定义分区列 ORDER BY column_name -- 排序列,可以有多个字段 ) AS row_num -- 别名 ``` - 当指定了 `PARTITION BY` 子句时,会先按照给定的列将数据分成若干个逻辑上的子集(即分区),再在每个子区内独立计算行号[^1]。 - 如果未指定 `PARTITION BY`,则整个结果集视为单一分区[^2]。 #### 实际应用场景举例 假设有一个商品库存表 `goo_sku`,其中包含商品名称 (`goods_name`) 和创建日期 (`create_date`) 字段。为了获取相同名字的商品列表,并且对于每一个重复的名字都依据其创建时间降序排列的同时赋予它们连续编号,可采用下面这条 SQL 查询命令: ```sql SELECT goods_name, create_date, ROW_NUMBER() OVER ( PARTITION BY goods_name ORDER BY create_date DESC ) AS rn FROM goo_sku; ``` 上述代码片段将会返回一张表格,其中包括所有具有相同 `goods_name` 的记录以及基于这些记录各自的 `create_date` 属性所生成的一系列递减整数作为新添加的 `rn` 列值[^4]。 #### 复杂案例分析 考虑另一个例子,假如存在名为 `orders` 的订单详情表,里面存储着顾客 ID(`customer_id`)、购买金额(`purchase_amount`)以及其他相关信息。现在想要找出每位客户最近三次购物的信息,可以通过组合使用 `ROW_NUMBER()` 来实现这一目标: ```sql WITH RankedOrders AS( SELECT *, ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY purchase_date DESC) as rank FROM orders ) SELECT * FROM RankedOrders WHERE rank <= 3; ``` 这里首先利用公共表达式(CTE)构建了一个临时视图 `RankedOrders` ,在这个过程中通过调用 `ROW_NUMBER()` 对于每一位客户的交易进行了排名;之后在外层查询里只选取那些排位小于等于三的结果项[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值