SQL 中的窗口函数

SQL 中的窗口函数(Window Functions)是一种特殊的函数,它可以在查询结果的某个区间内执行计算,而不仅仅是对单个行进行计算。

以下是一些常用的窗口函数:

1、ROW_NUMBER()

ROW_NUMBER() 函数可以给查询结果的每一行分配一个唯一的数字。通常,我们可以使用 ROW_NUMBER() 来按照特定的列对查询结果进行排序。

例如,以下 SQL 查询会按照 “sales” 表中 “amount” 列的降序排列,并给每行分配一个唯一的数字:

SELECT ROW_NUMBER() OVER (ORDER BY amount DESC) AS row_num, *
FROM sales;

2、RANK() 和 DENSE_RANK()

RANK() 和 DENSE_RANK() 函数可以为查询结果中的每一行分配排名。不同之处在于,如果有多个行具有相同的值,则 DENSE_RANK() 不会跳过排名

例如,以下 SQL 查询会按照 “sales” 表中 “amount” 列的升序排列,并为每个值分配一个排名:


SELECT amount, RANK() OVER (ORDER BY amount) AS rank,
       DENSE_RANK() OVER (ORDER BY amount) AS dense_rank
FROM sales;

3、SUM()、AVG()、MIN() 和 MAX()

SUM()、AVG()、MIN() 和 MAX() 函数可以用于计算查询结果的某个区间内的汇总、平均值、最小值和最大值。

例如,以下 SQL 查询会计算 “sales” 表中 “amount” 列的累计和,并为每个值分配一个唯一的数字:

SELECT amount, SUM(amount) OVER (ORDER BY date) AS running_total
FROM sales;

以上是一些常用的窗口函数,窗口函数在 SQL 中使用非常广泛,并且可以让我们在查询结果中执行更复杂的计算和分析。

案例

分数排名
在这里插入图片描述
在这里插入图片描述
sql语句:

# Write your MySQL query statement below
select score,dense_rank() 
over (order by score desc) as 'rank' 
from Scores;
<think>好的,我现在需要回答用户关于SQL窗口函数的使用教程和示例的问题。首先,我需要回顾窗口函数的基本概念和分类,确保自己理解正确。根据用户提供的引用内容,特别是引用[3]中的内容,窗口函数的结构包括窗口函数名称、表达式和OVER子句,其中OVER子句包含分区、排序和窗口大小选项。 接下来,我应该按照逻辑结构来组织回答。首先介绍什么是窗口函数,然后说明其语法结构,再分类讲解不同类型的窗口函数,比如排名函数、聚合函数、分布函数等,并给出每个类别的示例。同时,要注意用户提到的注意事项,比如不能在WHERE等子句中直接使用窗口函数生成的列,需要作为子查询处理,这点在引用[1]中提到过,需要在教程中强调。 用户可能希望看到具体的示例,所以需要准备一些常见的应用场景,比如计算每个部门的平均工资、排名销售业绩等。同时,结合引用[2]中的窗口TVFs,可能需要提到不同的窗口类型,比如滚动窗口、滑动窗口和累积窗口,但根据用户的问题,可能更关注标准的SQL窗口函数,而不是Flink特定的TVFs,所以需要区分清楚。 另外,需要确保使用正确的LaTeX格式,所有行内数学表达式用$...$,独立公式用$$...$$。但在这个问题中,可能数学表达式较少,更多是代码示例。不过如果有涉及到计算的部分,比如计算移动平均,可能需要用到聚合函数配合窗口框架。 在生成相关问题的时候,应该围绕窗口函数的常见疑惑点,比如执行顺序、与GROUP BY的区别、性能优化等,同时参考用户示例中的问题结构,确保问题具有针对性。 现在,我需要检查是否有遗漏的部分,比如窗口函数的执行顺序、实际应用中的常见错误,或者如何优化使用窗口函数的查询。同时,要确保所有引用都正确标注,例如在注意事项部分添加引用[1],在语法结构部分引用[3]。 最后,确保回答结构清晰,分点明确,示例代码正确,并且语言流畅自然,符合中文表达习惯。这样用户能够逐步理解窗口函数的使用方法,并能够应用到实际场景中。</think>### SQL窗口函数使用教程 #### 一、窗口函数简介 窗口函数(Window Function)用于在查询结果集的特定“窗口”(即行的子集)上执行计算,同时保留原始行的详细信息。与聚合函数不同,窗口函数不会将多行合并为一行,而是为每一行返回一个计算结果[^3]。 #### 二、基本语法 ```sql SELECT window_function(expression) OVER ( PARTITION BY partition_expression ORDER BY order_expression [frame_clause] ) AS alias FROM table; ``` - **`window_function`**:窗口函数名称(如`ROW_NUMBER()`, `SUM()`等)。 - **`PARTITION BY`**:将数据划分为多个分区,窗口函数在每个分区内独立计算。 - **`ORDER BY`**:定义分区内的排序规则。 - **`frame_clause`**:定义窗口范围(如`ROWS BETWEEN 3 PRECEDING AND CURRENT ROW`)[^3]。 --- #### 三、常用窗口函数分类与示例 ##### 1. 排名函数 - **`ROW_NUMBER()`**:为每行分配唯一序号。 ```sql SELECT name, salary, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank FROM employees; ``` - **`RANK()`**:允许并列排名,后续序号跳过重复值。 ```sql SELECT product, sales, RANK() OVER (ORDER BY sales DESC) AS sales_rank FROM products; ``` ##### 2. 聚合函数 - **`SUM()`/`AVG()`**:计算分区内的总和或平均值。 ```sql SELECT date, revenue, SUM(revenue) OVER (PARTITION BY month ORDER BY date) AS cumulative_revenue FROM sales; ``` ##### 3. 分布函数 - **`NTILE(n)`**:将数据分为`n`组并分配组号。 ```sql SELECT student_id, score, NTILE(4) OVER (ORDER BY score DESC) AS quartile FROM exam_results; ``` ##### 4. 前后值函数 - **`LAG()/LEAD()`**:访问前一行或后一行的数据。 ```sql SELECT month, revenue, LAG(revenue, 1) OVER (ORDER BY month) AS prev_month_revenue FROM monthly_sales; ``` --- #### 四、注意事项 1. **窗口函数执行顺序** 窗口函数在`WHERE`、`GROUP BY`、`HAVING`之后执行,因此不能在上述子句中直接引用窗口函数生成的列。需通过子查询实现[^1]: ```sql SELECT * FROM ( SELECT name, AVG(salary) OVER (PARTITION BY department) AS avg_salary FROM employees ) AS subquery WHERE avg_salary > 10000; ``` 2. **窗口框架(Frame Clause)** 通过`ROWS`或`RANGE`定义窗口范围: ```sql SELECT date, revenue, AVG(revenue) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg FROM sales; ``` --- #### 五、应用场景 1. **累计计算**:如累计销售额、移动平均。 2. **排名与分组分析**:如部门内薪资排名。 3. **数据对比**:比较当前行与前后行的差异。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值