關于MySQL的ORDER BY排序詳解
目錄
- 前言
- ORDER BY 語法
- 實踐出真知
- 實踐準備
- 靜態排序
- 動態排序
- 總結
前言
工作中常常會使用ORDER BY進行排序,了解ORDER BY多種排序方式是非常有必要的。
ORDER BY 排序可以分為靜態排序和動態排序,當然這個靜態和動態是我自己取的名字,其他地方找不到。
ORDER BY 語法
ORDER BY column1 ASC/DESC, column2 ASC/DESC.....
column代表一個列字段,ORDER BY可以允許多個字段進行排序,當字段后面顯式說明是升序(ASC)或者降序(DESC)時,默認是ASC。
實踐出真知
實踐準備
先準備一張orders表
CREATE TABLE `orders` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT "主鍵", `create_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT "創建時間", `update_date` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT "修改時間", `status` tinyint(2) NOT NULL DEFAULT "1" COMMENT "狀態", `is_deleted` bit(1) NOT NULL DEFAULT b"0" COMMENT "是否刪除", PRIMARY KEY (`id`)) ENGINE=InnoDB
表里存放著9條數據
靜態排序
所謂靜態排序就是ORDER BY后面排序的字段是固定不變的,不會根據排序字段的值的變化而變化。
舉個栗子:
SELECT * FROM orders ORDER BY id
上面這條SQL語句不會根據id的值變化字段id隨之變化。這類排序就是靜態排序。
ORDER BY后面排序字段可以跟1個或者多個,1個排序字段的就是單字段排序,多個字段的就是多字段排序。單字段排序比較簡單,上面的SQL就是單字段排序。
多字段排序中要特別注意一點的是有時選擇了多個字段進行排序,但并沒有達到期望的結果,因為多字段排序是分組排序。
舉個栗子說明一下:
列1:
SELECT * FROM orders ORDER BY id , create_date DESC
運行結果如下:
上面這條SQL語句看似是按id升序,create_date降序,通過運行結果可以看到實則create_date排序并沒有起作用。
在ORDER BY排序中是根據第一個字段先排序,然后在第一個字段的基礎上再排序,如果第一個字段的值是不重復的,排序后后面的字段就失去了作用了。
列2:
SELECT * FROM orders ORDER BY `status` , create_date DESC
運行結果:
列2的SQL中我們把id字段排序換成了status字段排序,由于status字段的值是重復的,從結果中我們可以看到在status字段排序完成之后,create_date字段的排序就起作用了,就按照我們指定的DESC進行排序了。
所以多字段進行排序,實則是分組排序,排序的第一個字段的值如果不重復,后面的排序字段將失效。第一個字段的值如果重復,第二個字段將會在第一個字段重復組內進行排序,第三個字段會在前兩個字段排好序的基礎上排序,以此類推。
動態排序
動態排序和靜態排序相反(這就是一句廢話???)。所謂動態排序就是ORDER BY后面的排序字段會根據值的變化而變化。工作中應該會常常用到,比如在a=1時根據b字段進行排序,在a=2時根據c字段進行排序。這種的就稱之為動態排序。
動態排序一般都會搭配著判斷條件進行排序的,比如 Case when、if等。下面就分別使用Case和if條件判斷進行排序。
- CASE WHEN 動態排序
SELECT *FROM ordersORDER BY `status` DESC, CASEWHEN `status` = 2 THEN create_dateEND DESC, CASEWHEN `status` = 4 THEN update_dateEND
運行結果如下:
當status=2時根據create_date降序,當status=4時根據update_date升序。從結果中也可以看到達到了我們想要的效果。
- IF 動態排序
IF 動態排序跟使用CASE WHEN排序類似,也是對字段進行判斷。
SELECT *FROM ordersORDER BYIF (`status` = 3, "0", "1"), `status`, create_date DESC
運行結果:
在這段SQL中,運行結果可以分為兩部分status=3是一部分,其余是另一部分,此時IF判斷其實是附加了一個隱藏字段,status=3時返回0,否則返回1,然后再根據返回結果進行升序排序。從下面這段SQL看會更清晰。
SELECT id, `status`,IF (`status` = 3, "0", "1") hidden_column, create_date, update_date, is_deletedFROM ordersORDER BYIF (`status` = 3, "0", "1"), `status`, create_date DESC
就是對hidden_column進行排序之后,再對status進行升序排序,接著再對create_date降序排序,結果也是一樣的。
ORDER BY為什么支持動態排序呢?是因為ORDER BY執行順序優先級比較低,它是在獲取到結果之后才進行排序的,在獲取到結果集之后可以進行一些其他操作,就像我們從數據庫獲取結果集對其進行排序一樣,所以它可以支持動態排序。除此之后ORDER BY后面可以搭配其他函數或者查詢條件使用,比如LIKE、CONCAT、IN或者一些其他的函數都可以,感興趣的自己可以試一試,下面就拿CONCAT做個測試。
比如可以將兩個字段拼接后排序:
SELECT `status` , id ,CONCAT(`status` , id) FROM ordersORDER BY CONCAT(`status`, id) DESC
結果:
總結
- mysql 中排序默認是按照升序ASC進行排序的
- 在多字段進行排序時,實則是分組排序。多字段排序會將每個分組劃分為一個個小的單元,在這一個個小的單元內再進行排序。
- ORDER BY的執行順序優先級相對較低,是在查詢結果出來以后再進行排序。
- ORDER BY可以搭配函數或者一些查詢條件使用。
到此這篇關于關于MySQL的ORDER BY排序詳解的文章就介紹到這了,更多相關MySQL的ORDER BY排序內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!
相關文章: