MariaDB Window Functions窗口函數分組取TOP N記錄

窗口函數在MariaDB10.2版本里實現,其簡化了複雜SQL的撰寫,提升了可讀性。bash

在某些方面,窗口函數相似於彙集函數, 但它不像彙集函數那樣每組只返回一個值,窗口函數能夠爲每組返回多個值。ide

做爲一種高級查詢功能,解釋起來並不是易事。提供窗口函數介紹的最佳方法是經過示例,讓咱們看看窗口函數實現分組取TOP N記錄。函數


表結構spa

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `SName` varchar(100) DEFAULT NULL COMMENT '姓名',
  `ClsNo` varchar(100) DEFAULT NULL COMMENT '班級',
  `Score` int(11) DEFAULT NULL COMMENT '分數',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
insert into `student`(`id`,`SName`,`ClsNo`,`Score`) values 
(1,'AAAA','C1',67),(2,'BBBB','C1',55),(3,'CCCC','C1',67),(4,'DDDD','C1',65),
(5,'EEEE','C1',95),(6,'FFFF','C2',57),(7,'GGGG','C2',87),(8,'HHHH','C2',74),
(9,'IIII','C2',52),(10,'JJJJ','C2',81),(11,'KKKK','C2',67),(12,'LLLL','C2',66),
(13,'MMMM','C2',63),(14,'NNNN','C3',99),(15,'OOOO','C3',50),(16,'PPPP','C3',59),
(17,'QQQQ','C3',66),(18,'RRRR','C3',76),(19,'SSSS','C3',50),(20,'TTTT','C3',50),
(21,'UUUU','C3',64),(22,'VVVV','C3',74);

查詢結果.net

圖片.png


如今取出各班前三名blog

SELECT SName,ClsNo,Score,
dense_rank() OVER (PARTITION BY ClsNo ORDER BY Score DESC) AS top3
FROM student;

使用窗口函數須要OVER關鍵字。 dense_rank()是一個特殊的排名函數,只能做爲「窗口函數」使用,不能在沒有OVER子句的狀況下使用。
圖片

OVER子句支持一個名爲PARTITION BY的關鍵字,它與GROUP BY的工做方式很是類似。 使用PARTITION BY,咱們將按照班級分組,並單獨計算排名行號。get

圖片.png

咱們能夠看到每一個班級都有一個單獨的排名順序。it


窗口函數的計算髮生在WHERE,GROUP BY和HAVING子句完成以後,在ORDER BY以前。固這裏須要外包一層派生表獲得最終排名結果。io

SELECT * FROM
(SELECT SName,ClsNo,Score, dense_rank() OVER (PARTITION BY ClsNo ORDER BY Score DESC) AS top3 FROM student) AS tmp
WHERE tmp.top3 <=3 ORDER BY tmp.ClsNO ASC,tmp.Score DESC;

圖片.png

經過窗口函數,很是輕鬆的實現分析需求,而使用傳統的方法,會很是複雜,SQL理解起來也很困難。

例:

SELECT a.id,a.SName,a.ClsNo,a.Score FROM student a 
LEFT JOIN student b ON a.ClsNo=b.ClsNo
AND a.Score<b.Score 
GROUP BY a.id,a.SName,a.ClsNo,a.Score HAVING COUNT(b.id)<3
ORDER BY a.ClsNo,a.Score DESC;

圖片.png


參考:

https://mariadb.com/kb/en/library/window-functions-overview/

https://blog.csdn.net/acmain_chm/article/details/4126306

相關文章
相關標籤/搜索