MySQL利用UNION連線2個查詢排序失效詳解
阿新 • • 發佈:2020-01-09
概述
UNION
連線資料集關鍵字,可以將兩個查詢結果集拼接為一個,會過濾掉相同的記錄
UNION ALL
連線資料集關鍵字,可以將兩個查詢結果集拼接為一個,不會過濾掉相同的記錄
今天在接到一個需求的時候使用了UNION進行查詢後發現,如果兩個查詢分別使用ORDER BY後拼接居然無法成功排序,經過了好一番折騰,記錄下
表結構及資料
-- 建立表 CREATE TABLE test_user ( ID int(11) NOT NULL AUTO_INCREMENT,USER_ID int(11) DEFAULT NULL COMMENT '使用者賬號',USER_NAME varchar(255) DEFAULT NULL COMMENT '使用者名稱',AGE int(5) DEFAULT NULL COMMENT '年齡',COMMENT varchar(255) DEFAULT NULL COMMENT '簡介',PRIMARY KEY (ID) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; -- 資料插入語句 INSERT INTO test_user (ID,USER_ID,USER_NAME,AGE,COMMENT) VALUES ('1','111','開心菜鳥','18','今天很開心'); INSERT INTO test_user (ID,COMMENT) VALUES ('2','222','悲傷菜鳥','21','今天很悲傷'); INSERT INTO test_user (ID,COMMENT) VALUES ('3','333','認真菜鳥','30','今天很認真'); INSERT INTO test_user (ID,COMMENT) VALUES ('4','444','高興菜鳥','今天很高興'); INSERT INTO test_user (ID,COMMENT) VALUES ('5','555','嚴肅菜鳥','今天很嚴肅');
預設表資料顯示如下
執行結果分析
-- 查詢1 SELECT * FROM test_user u ORDER BY AGE
結果集1
-- 查詢2 -- 使用UNION ( SELECT * FROM test_user u ORDER BY AGE ) UNION ( SELECT * FROM test_user u ORDER BY AGE ); -- 查詢3 -- 使用UNION ALL ( SELECT * FROM test_user u ORDER BY AGE ) UNION ALL ( SELECT * FROM test_user u ORDER BY AGE )
結果集2:使用UNION
由於UNION會合並相同的記錄(與DISTINCT實現相同效果),因此此處顯示僅有5條記錄
結果集3:使用UNION ALL
如果需要使用UNION ALL又需要進行排序,則要將其作為一個子查詢來查
-- 查詢4 -- 將UNION ALL作為子查詢並進行排序 SELECT * FROM ( ( SELECT * FROM test_user u ORDER BY AGE ) UNION ALL ( SELECT * FROM test_user u ORDER BY AGE ) ) a ORDER BY AGE;
結果集4
改進
在經過一番搜尋相關的經驗後發現,是我之前有些畫蛇添足了,原來可以在不使用子查詢即可完成排序的方法:
-- 查詢5 -- 第一個查詢不使用排序,如果使用的話不加括號會報錯(這也是我之前為什麼會想用子查詢的原因而沒有想過這種方式了) SELECT * FROM test_user u UNION ALL SELECT * FROM test_user u ORDER BY AGE
執行出來的結果集與結果集4是相同的,此處就不再粘出結果。
結論
當我們使用UNION(或者UNION ALL)語句時,如果UNION的兩個結果集在單獨排序後再拼接,則他們的ORDER BY是失效的。如果我們要進行排序有以下兩種方法:
- 將它們作為子查詢再ORDER BY查詢一次(還是建議使用方法2,子查詢太不簡潔了)
- 在第一個結果集中不使用排序,且不用括號分隔,而在第二個結果集後使用ORDER BY
參考連結
cnblogs:MySQL中UNION和UNION ALL的使用
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對我們的支援。