MySQL學習筆記:三種組內排序方法


  由於MySQ沒有提供像Oracle的dense_rank()或者row_number() over(partition by)等函數,來實現組內排序,想實現這個功能,還是得自己想想辦法,最終通過創建行號實現。

方法一:


 

  1.建立測試表

# 建表 DROP TABLE test; CREATE TABLE test ( myNAME VARCHAR (10), name1 VARCHAR (10), count1 BIGINT );

  2.刪除原有數據

# 刪除原有數據 DELETE FROM test; SELECT * FROM test;

  3.插入數據

# 插入數據 INSERT INTO test VALUES('1','a',2); INSERT INTO test VALUES('1','b',1);; INSERT INTO test VALUES('1','c',4); INSERT INTO test VALUES('1','d',5); INSERT INTO test VALUES('1','e',7); INSERT INTO test VALUES('1','f',8); INSERT INTO test VALUES('2','g',9); INSERT INTO test VALUES('2','h',0); INSERT INTO test VALUES('2','i',21); INSERT INTO test VALUES('2','j',3); INSERT INTO test VALUES('2','k',4); INSERT INTO test VALUES('2','1',56); INSERT INTO test VALUES('3','m',67); INSERT INTO test VALUES('3','n',89); INSERT INTO test VALUES('3','o',12); INSERT INTO test VALUES('3','p',22); INSERT INTO test VALUES('3','q',23); INSERT INTO test VALUES('3','r',42); INSERT INTO test VALUES('3','s',26);

  4.查詢

# 查詢 SELECT * FROM test;

  5.構造行號rownum

#---- 構造rownum ----
SELECT b.myNAME, b.name1, b.count1, IF(@name = b.myNAME, @rank := @rank + 1, @rank := 1) -- 3.判斷name是否等於此行的myNAME
    AS rank,   -- 如果是,則rank自增;如果不是,則初始化rank=1
    @name := b.myNAME FROM (SELECT myNAME, name1, count1 FROM test ORDER BY myNAME ASC, count1 DESC) b,  -- 1.先進行子查詢 排序
(SELECT @rownum := 0, @name := NULL, -- 2.初始化rownum=0,name=NULL, rank=0
    @rank := 0) a;

  6.篩選組內前五(即行數小於等於5的行)

SELECT myNAME, name1, count1, rank FROM (SELECT b.myNAME, b.name1, b.count1, IF(@name = b.myNAME, @rank := @rank + 1, @rank := 1) -- 3.判斷name是否等於此行的myNAME
    AS rank,   #-- 如果是,則rank自增;如果不是,則初始化rank=1
    @name := b.myNAME FROM (SELECT myNAME, name1, count1 FROM test ORDER BY myNAME ASC, count1 DESC) b,  -- 1.先進行子查詢 排序
(SELECT @rownum := 0, @name := NULL, -- 2.初始化rownum=0,name=NULL, rank=0
    @rank := 0) a) result WHERE rank <=5;

 

方法二:


 

  1.關聯

SELECT * 
FROM test a JOIN test b ON a.`myNAME` = b.`myNAME` AND a.`count1` <= b.`count1`;

  2.排序

SELECT * 
FROM test a JOIN test b ON a.`myNAME` = b.`myNAME` AND a.`count1` <= b.`count1` ORDER BY a.`myNAME` ASC, a.`count1` DESC;

  3.最終實現

SELECT a.myNAME,a.name1,a.count1,COUNT(*) AS rank FROM test a JOIN test b ON a.`myNAME` = b.`myNAME` AND a.`count1` <= b.`count1` GROUP BY a.`myNAME`,a.`name1`,a.`count1` ORDER BY a.`myNAME` ASC, a.`count1` DESC;

 

方法三:


 

  其實方法三只是方法二的補充,針對有數據相等的情況。

SELECT a.myNAME, a.name1, a.count1, COUNT(1) AS rank FROM test AS a, test AS b WHERE a.myNAME = b.myNAME AND a.count1 < b.count1 OR (a.count1 = b.count1 AND a.myNAME <= b.myNAME) GROUP BY a.myNAME, a.name1, a.count1 ORDER BY a.myNAME ASC, rank ASC;

END 2018-05-2510:54:26


免責聲明!

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



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