mysql窗口函數及用法


mysql窗口函數及用法

首先推薦:MYSQL窗口函數 - 知乎 (zhihu.com)這篇文章,寫得非常詳細

含義:窗口函數也叫OLAP函數(Online Anallytical Processing,聯機分析處理),可以對數據進行實時分析處理。

tips: 例子來源於leetcode or 牛客網

分類:

  • 專用窗口函數:rank(),dense_rank(),row_number()
  • 匯總函數:max(),min(),count(),sum(),avg()

語法:

select 窗口函數 over (partition by 用於分組的列名, order by 用於排序的列名)

一、rank() 函數

說明

  • rank()是排序函數,括號中不需要有參數;
  • 通過partition by將班級分類,相當於之前用過的group by子句功能,但是group by子句分類匯總會改變原數據的行數,而用窗口函數自救保持原行數;
  • 通過order by將成績降序排列,與之前學的order by子句用法一樣,后邊可以升序asc或者降序desc;

注意:窗口函數是對where后者group by子句處理后的結果進行操作,因此按照SQL語句的運行順序,窗口函數一般放在select子句中。

數據表:

+----+-------+
| Id | Score |
+----+-------+
| 1  | 3.50  |
| 2  | 3.65  |
| 3  | 4.00  |
| 4  | 3.85  |
| 5  | 4.00  |
| 6  | 3.65  |
+----+-------+             

leetcode 178. 分數排名

在rank()函數,如果有並列情況,會占用下一個名次的位置

SELECT Score ,rank() over(order by Score desc) as 'Rank' from Scores;
//{"headers": ["Score", "Rank"], "values": [[4.00, 1], [4.00, 1], [3.85, 3], [3.65, 4], [3.65, 4], [3.50, 6]]}

在dense_rank()函數,如果有並列情況,則不會占用下一個名次的位置

SELECT Score ,dense_rank() over(order by Score desc) as 'Rank' from Scores;
//{"headers": ["Score", "Rank"], "values": [[4.00, 1], [4.00, 1], [3.85, 2], [3.65, 3], [3.65, 3], [3.50, 4]]}

在row_number()函數中,會忽略並列的情況

SELECT Score ,row_number() over(order by Score desc) as 'Rank' from Scores;
{"headers": ["Score", "Rank"], "values": [[4.00, 1], [4.00, 1], [3.85, 2], [3.65, 3], [3.65, 3], [3.50, 4]]}

二、聚合函數 ( leetcode 184. 部門工資最高的員工

Employee 表包含所有員工信息,每個員工有其對應的 Id, salary 和 department Id。
+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+
Department 表包含公司所有部門的信息。
+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

作用:聚合函數作為窗口函數,是起到"累加/累計"的效果,比如,就是截止到本行,最大值?最小值是多少

與專用窗口函數的區別:括號中需要有指定列,不能為空

select Department,Employee,Salary from (select d.Name Department,e.Name Employee,e.Salary, Max(Salary) over (PARTITION BY d.Name) as max from Employee e join Department d on e.DepartmentId = d.Id) s where Salary = max

//{"headers": ["Department", "Employee", "Salary"], "values": [["IT", "Jim", 90000], ["IT", "Max", 90000], ["Sales", "Henry", 80000]]}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM