窗口函數可以理解為記錄集合,每條記錄都要在窗口內執行函數,多行聚合為多行。MYSQL從8.0版本開始才支持窗口函數
ROW_NUMBER() #分區中的當前行號
RANK() #當前行在分區中的排名,含序號間隙
DENSE_RANK() #當前行在分區中的排名,不含序號間隙
PERCENT_RANK() #百分比等級值
CUME_DIST() #累計分配值
FIRST_VALUE() #窗口中的第一個行參數值
LAST_VALUE() #窗口中的最后一行函數值
LAG() #分區中指定行落后於當前行的參數值
LEAD() #分區中領先當前行的參數值
NTH_VALUE() #從第N行窗口框架的參數值
NTILE(N) #分區中當前的桶號
1. row_number()
SELECT * FROM (SELECT row_number () OVER ( PARTITION BY user_no ORDER BY create_date DESC ) AS row_num, order_id, user_no, amount, create_date FROM order_tab) t WHERE row_num = 1
SELECT * FROM (SELECT row_number () over w AS row_num, order_id, user_no, amount, create_date FROM order_tab window w AS ( PARTITION BY user_no ORDER BY create_date DESC )) t WHERE row_num = 1
SELECT * FROM (SELECT order_id, user_no, amount, AVG(amount) over w AS avg_num, create_date FROM order_tab window w AS ( PARTITION BY user_no ORDER BY create_date DESC ROWS BETWEEN 1 preceding AND 1 following )) t
2. RANK()
SELECT * FROM ( SELECT row_number() over(PARTITION BY user_no ORDER BY amount DESC ) AS row_num1, rank() over(PARTITION BY user_no ORDER BY amount DESC ) AS row_num2, dense_rank() over(PARTITION BY user_no ORDER BY amount DESC ) AS row_num3, order_id,user_no,amount,create_date FROM order_tab ) t
3. DENSE_RANK()
SELECT * FROM ( SELECT rank() over w AS row_num, percent_rank() over w AS percent, order_id,user_no,amount,create_date FROM order_tab window w AS (PARTITION BY user_no ORDER BY amount DESC) ) t
4. NTILE()
SELECT * FROM ( SELECT ntile(3) over w AS nf, order_id,user_no,amount,create_date FROM order_tab window w AS (PARTITION BY user_no ORDER BY amount DESC) ) t
5. NTH_VALUE()
SELECT * FROM ( SELECT ntile(3) over w AS nf, nth_value(order_id,3) over w AS nth, order_id,user_no,amount,create_date FROM order_tab window w AS (PARTITION BY user_no ORDER BY amount DESC) ) t
6. 聚合函數作為窗口函數
SELECT order_id,user_no,amount,create_date, SUM(amount) over w AS sum1, AVG(amount) over w AS avg1, MAX(amount) over w AS max1, MIN(amount) over w AS min1, COUNT(amount) over w AS count1 FROM order_tab window w AS (PARTITION BY user_no ORDER BY order_id)