Mysql高階自定義排序

2023-08-29 06:00:32

Mysql高階自定義排序

嗨,大家好,我是遠碼,隔三岔五給大家分享一點工作的技術總結,花費的時間不多,幾分鐘就行,謝謝!

Mysql對我們碼農來說是在熟悉不過的日常了,就不在介紹它的基礎用法了,今天我們來簡單聊聊它的一個基本高階使用。

一、問題引入

今天看到一個小夥伴在寫一個表查詢排序時,整的有點焦頭爛額,大致邏輯是這樣的:有一個學生表(主要表欄位包括,主鍵:id,姓名:name,階段:stage),其中stage的值包括(初中、高、大學),需要按照使用者的一下需求指定排序:初中、高總、大學,如果使用系統預設的排序,始終達不到要求,那該如果實現呢?

二、問題解決方式

咋一看,這不就是自定義排序嘛,藉此機會就聊聊自定義排序的實現方式吧,大概有以下幾種實現方式:

(一)FIELD函數實現

FIELD()函數返回值列表中值的索引位置,語法:FIELD(value, val1, val2, val3, ...),簡單的說:改函數就是返回value在集合(val1,val2,val3,...)中對應的索引位置,結合上面的需求,是不是可以這樣來使用,學生表stage值就對映函數的value,(初中、高總、大學)就對映函數的值列表集合,如果學生.stage=初中,返回值不是就是1;學生.stage=高中,返回值不是就是2;學生.stage=大學,返回值不是就是3,在對結果值排一個序,不就滿足要求了嘛,話不多說上程式碼:

SELECT id,name,stage FROM `user` ORDER BY FIELD(stage,"初中","高中","大學") asc;

查詢結果:搞定

 

(二)LOCATE函數實現

FIELD(substr,str,pos)函數返回字串substr在str中第一次出現的位置,pos可空,表示開始座標,例如:

SELECT LOCATE("初中","初中,高中,大學");--返回1
SELECT LOCATE("高中","初中,高中,大學");--返回2
SELECT LOCATE("大學","初中,高中,大學");--返回3

這不就正好滿足上述需求嘛,話不多說上程式碼:

SELECT id,name,stage FROM `user` ORDER BY LOCATE(stage,"初中,高中,大學") asc;

  

(三)INSTR函數實現

INSTR(str,substr)函數返回字串str中substr第一次出現的位置,例如:

SELECT INSTR("初中,高中,大學","初中");-- 返回1
SELECT INSTR("初中,高中,大學","高中");-- 返回2
SELECT INSTR("初中,高中,大學","大學");-- 返回3

  

這不就正好滿足上述需求嘛,話不多說上程式碼:

SELECT id,name,stage FROM `user` ORDER BY INSTR("初中,高中,大學",stage) asc;

  

 

(四)CASE WHEN語句實現

CASE WHEN簡單的說就是根據不同的條件將其轉換為指定的值,比如:根據stage 的不同值轉換為對應的數位,在對結果排序滿足要求了,話不多說上程式碼:

SELECT id,name,stage FROM `user` ORDER BY

CASE stage

   WHEN "初中" THEN 1

WHEN "高中" THEN 2

WHEN "大學" THEN 3

   ELSE 4 END  asc;

  

 

(五)資料表字典實現

資料表字典思路就是需要單獨建立一個stage 的值對映對應關係表,最後通過關聯查詢,並對根據對映值排序,正好能夠滿足上述要求,話不多說上程式碼:

SELECT u.id,u.name,u.stage FROM `user` as u  

JOIN stage_dic as sd on u.stage = sd.stage

ORDER BY sd.code asc;

  

 

 

三、問題總結

通過上面的5種排序,都能夠解決問題引入提到的自定義排序需求。這5種排序,既有相同的應用場景,也有各自不同的應用場景,在實際使用中還需要根據實際情況選擇不同的排序方式,下面對其做一個簡單的總結:

  1. 針對簡單列舉值皆可實現,數位表字典更靈活
  2. LOCATE與INSTR最終效果一致,引數顛倒,INSTR區分大小寫,LOCATE不區分大小寫
  3. 函數雖好,使用需要謹慎,能夠在儲存時就處理好資料,就不要在查詢時通過函數計算來解

END
為了更高的交流,歡迎大家關注我的公眾號,掃描下面二維條碼即可關注,謝謝: