SQL基础系列(八)——排序、分组排序(RANK)

本文介绍了SQL窗口函数的应用,特别是排序功能,如RANK、DENSE_RANK和ROW_NUMBER。通过示例展示了如何在SELECT语句中进行分组排序,并提供了解决特定查询问题的思路,如找出每个玩家的首次登录设备号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

窗口函数可以进行排序,生成序号等操作,结合查询语句,可以进行一些较为复杂的查询。本文主要介绍窗口函数的用法,以及相关的查询示例。

示例

现在有成绩表grade

calssnamegrade
高一一班张三79
高一一班李四86
高一一班王武87
高一二班王六90
高一二班张望76
高一二班刘大88
SELECT *,RANK() OVER (PARTITION BY class ORDER BY grade) AS ranking
FROM grade;

在SELECT 子句中,可对已有数据进行分组排序。在上例中,即按照班级(class)分组,再对每个班级的学生成绩(grade)进行排序。

查询结果中展示排名数字。

执行SQL语句后的结果:

calssnamegraderanking
高一一班王武871
高一一班李四862
高一一班张三793
高一二班王六901
高一二班刘大882
高一二班张望763

语法解析

<窗口函数> OVER (PARTITON BY 分组列 ORDER BY 排序列)

之所以叫窗口函数,是因为通过PARTITION BY可将数据划分为不同的数据范围,这个数据范围即称为窗口。如上例中,将数据按照班级划分为不同的数据范围。(同GROUP BY的分组相似)

用于排序的窗口函数主要包括:

  • RANK

计算排序时,如果存在相同位次的记录,则会跳过之后的位次。

例:有三条记录并列排第一,则:1,1,1,4

  • DENSE_RANK 

计算排序,存在相同位次的记录,不会跳过之后的位次。

例:有三条记录并列排第一,则1,1,1,2

  • ROW_NUMBER

连续排位

例:有三条记录并列排第一,则1,2,3,4

语句示例:

RANK() OVER (PARTITON BY class ORDER BY grade) 

语句解析: 

RANK() :函数后面的括号为习惯用法。里面不需要放置参数。上述其他窗口函数均使用括号。

PARTITON BY :设定排序的对象范围,上例中,按照不同的班级进行排名,因此PARTITON BY class。

ORDER BY:排序标准。上例中,按照每个班级中的成绩排名,因此ORDER BY grade。

此语法仅用在SELECT子句之后,为查询结果增添排序列。在SQL语句执行时,执行FROM中的数据表,再执行WHERE条件,最后才会在执行SELECT子句时,按照函数语句,对查询结果进行分组排序。

参考题目

链接:在gameList表中(player_id, event_d__牛客网
来源:牛客网

在gameList表中(player_id, event_date)是主键,如何显示每个玩家(player_id)首次登录的设备号(device_id),并同时显示玩家ID(player_id)? 

player_id

device_id

event_date

games_played

111

21

2020-03-01

5

111

21

2020-01-02

6

212

33

2020-09-03

1

322

11

2020-01-21

0

322

44

2020-03-02

5

解题思路:

子查询排序:对每个玩家的信息,按照登陆日期进行排序。将子查询结果作为临时表。

对子查询的结果,保留每个玩家排名第一的数据。

SELECT player_id, device_id 
FROM
(SELECT *,RANK() OVER (PARTITION BY player_id ORDER BY event_date) AS ranking FROM gamelist) 
WHERE ranking=1;

在上述语句中,执行子查询产生的结果如下:

player_id

device_id

event_date

games_played

ranking

111

21

2020-03-01

5

2

111

21

2020-01-02

6

1

212

33

2020-09-03

1

1

322

11

2020-01-21

0

1

322

44

2020-03-02

5

2 

子查询语句中,根据每个玩家的登陆日期进行排序。

再找出排名为1的数据,即每个玩家最早登陆的数据,据此找出对应的玩家(player_id)和设备号(device_id)。

### 使用 C# 遍历文件夹中的文件 为了遍历目录中的所有文件,在 C# 中可以利用 `System.IO` 命名空间下的类来实现这一功能。下面是一个简单的例子,展示了如何读取特定路径下所有的文件名称并打印出来: ```csharp using System; using System.IO; class Program { static void Main(string[] args) { string path = @"C:\example_directory"; // 定义要遍历的目标文件夹路径 try { // 获取目标文件夹内所有文件的名字(不包括子文件夹内的) string[] files = Directory.GetFiles(path); Console.WriteLine("Files found:"); foreach (string file in files) { Console.WriteLine(file); } } catch (Exception e) { Console.WriteLine($"An error occurred: {e.Message}"); } } } ``` 如果还需要访问子文件夹及其内部的文件,则可以通过设置搜索选项参数为 `SearchOption.AllDirectories` 来递归地获取整个树状结构里的每一个文件。 ```csharp // 修改上述代码片段以包含子文件夹的内容 string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories); ``` 当处理大量文件时,考虑性能因素,可能更倾向于使用 `Directory.EnumerateFiles()` 方法代替 `GetFiles()`,因为前者会在迭代过程中逐个返回结果而不是一次性加载全部数据到内存中[^1]。 #### 处理大数量级文件的最佳实践建议 对于非常庞大的文件集合,推荐采用流式处理的方式,即随着程序运行逐步读取和处理文件列表的一部分而非全部。这有助于减少应用程序启动时间和资源占用率。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值