over函数的使用
与over函数结合的几个函数介绍 Row_number() over()、rank() over()和dense_rank()over()函数的使用 Select * from (select name,class,s,rank() over(partition by class order by s desc) mm from t2) where mm=1; 说明: 1.在求第一名成绩的时候,不能用row_number(),因为如果同班有2个并列第1,row_number()只返回一个结果; 2.Rank()和dense_rank()可以将所有的都查找出来: 区别:rank()是跳跃排序,有2个第一名时,接下来就是第3名; Dense_rank() 是连续排序,有2个第一名时仍然跟着第2名 ### over函数概述 在数据库查询语言SQL中,`over`函数是处理复杂数据分析的一个强大工具。它主要用于定义一个数据窗口,使得可以在该窗口内执行各种聚合操作,如排名、累计和等。`over`函数通常与`row_number()`、`rank()`、`dense_rank()`等函数配合使用,以实现对数据的复杂排序和分组需求。 ### `over(partition by)` 函数详解 `over(partition by)`用于将数据集划分为不同的分区或子集,并允许在每个分区内部执行特定的操作。这种方式非常适用于需要对不同类别或组的数据进行独立分析的情况。例如,在一个包含多个部门员工薪资信息的表中,我们可能希望分别计算每个部门的最高薪资,这时就可以使用`over(partition by deptno)`来实现这一功能。 #### 示例代码解析 ```sql SELECT * FROM ( SELECT name, class, s, rank() OVER(PARTITION BY class ORDER BY s DESC) AS mm FROM t2 ) WHERE mm = 1; ``` - **PARTITION BY**子句指定了按`class`字段进行分区,即对每个班级的学生进行单独排序。 - **ORDER BY**子句定义了每个班级内学生按`s`(假设代表分数)降序排列。 - **RANK() OVER()**函数计算每个班级学生的排名。 - 最后一层`WHERE mm = 1`筛选出每个班级的第一名。 ### `over(order by)` 函数详解 `over(order by)`则是按照指定的顺序对整个数据集进行排序,而不考虑分区。这在需要全局排序的情况下非常有用,比如计算公司所有员工的薪资排名等。 #### 示例代码解析 ```sql SELECT * FROM ( SELECT name, salary, row_number() OVER(ORDER BY salary DESC) AS rn FROM employees ); ``` - **ORDER BY salary DESC**表示根据`salary`字段降序排列所有员工。 - **ROW_NUMBER() OVER()**为每个员工分配一个唯一编号。 ### 开窗函数的窗口范围 除了上述的`PARTITION BY`和`ORDER BY`,`OVER`还可以定义窗口范围,即确定计算时所考虑的数据行范围。这可以通过`RANGE`或`ROWS`关键字来实现: - **RANGE**定义了一个基于值的窗口范围,即考虑那些与当前行具有相似值的行。 - **ROWS**则基于行的位置来定义窗口范围,即考虑固定数量的前/后行。 #### 示例代码解析 ```sql SELECT emp_id, salary, SUM(salary) OVER(ORDER BY salary ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING) AS running_total FROM employees; ``` - **SUM(salary) OVER()**计算当前行及其前后共5行的薪资总和。 - **ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING**定义了一个包括当前行在内的前后各两行的窗口范围。 ### 结合`row_number()`、`rank()`、`dense_rank()`的使用 #### 1. `ROW_NUMBER() OVER()` `ROW_NUMBER()`为每一行分配一个唯一的数字。当存在并列情况时,`ROW_NUMBER()`会继续递增,因此不适用于需要找出所有并列第一的情况。 #### 2. `RANK() OVER()` `RANK()`同样为每一行分配一个排名,但在遇到并列情况时会跳过相应的排名。例如,如果有两个第一,则下一个位置的排名将是第三而不是第二。 #### 3. `DENSE_RANK() OVER()` 与`RANK()`类似,`DENSE_RANK()`也为每一行分配一个排名,但不会出现跳号现象。即使有多行并列第一,下一行的排名依然是第二。 ### 总结 通过`OVER`函数,我们可以灵活地对数据进行分区、排序和聚合,从而满足复杂的数据分析需求。理解并掌握这些函数的使用方法对于提高数据分析能力至关重要。希望以上内容能帮助您更好地理解和应用这些强大的SQL特性。