日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL自定义排序函数FIELD()

發布時間:2023/12/20 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL自定义排序函数FIELD() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自:https://blog.csdn.net/lxz3000/article/details/6173873

MySQL可以通過field()函數自定義排序

格式:
field(value,str1,str2,str3,str4)

value與str1、str2、str3、str4比較,返回1、2、3、4,如遇到null或者不在列表中的數據則返回0. 這個函數好像Oracle中沒有專門提供(也可能是我沒有用到),不過自己實現這樣一個函數還是比較簡單的。

mysql> select * from driver_log order by name;+--------+-------+------------+-------+ | rec_id | name | trav_date | miles | +--------+-------+------------+-------+ | 1 | Ben | 2006-08-30 | 152 | | 9 | Ben | 2006-09-02 | 79 | | 5 | Ben | 2006-08-29 | 131 | | 8 | Henry | 2006-09-01 | 197 | | 6 | Henry | 2006-08-26 | 115 | | 4 | Henry | 2006-08-27 | 96 | | 3 | Henry | 2006-08-29 | 300 | | 10 | Henry | 2006-08-30 | 203 | | 7 | Suzi | 2006-09-02 | 502 | | 2 | Suzi | 2006-08-29 | 391 | +--------+-------+------------+-------+10 rows in set (0.00 sec) mysql> select * from driver_log order by field(name,'Suzi','Ben','Henry');+--------+-------+------------+-------+ | rec_id | name | trav_date | miles | +--------+-------+------------+-------+ | 2 | Suzi | 2006-08-29 | 391 | | 7 | Suzi | 2006-09-02 | 502 | | 1 | Ben | 2006-08-30 | 152 | | 9 | Ben | 2006-09-02 | 79 | | 5 | Ben | 2006-08-29 | 131 | | 8 | Henry | 2006-09-01 | 197 | | 6 | Henry | 2006-08-26 | 115 | | 4 | Henry | 2006-08-27 | 96 | | 3 | Henry | 2006-08-29 | 300 | | 10 | Henry | 2006-08-30 | 203 | +--------+-------+------------+-------+10 rows in set (0.00 sec) mysql> select * from driver_log order by field(name,'Suzi','Ben');+--------+-------+------------+-------+ | rec_id | name | trav_date | miles | +--------+-------+------------+-------+ | 10 | Henry | 2006-08-30 | 203 | | 8 | Henry | 2006-09-01 | 197 | | 6 | Henry | 2006-08-26 | 115 | | 4 | Henry | 2006-08-27 | 96 | | 3 | Henry | 2006-08-29 | 300 | | 7 | Suzi | 2006-09-02 | 502 | | 2 | Suzi | 2006-08-29 | 391 | | 5 | Ben | 2006-08-29 | 131 | | 9 | Ben | 2006-09-02 | 79 | | 1 | Ben | 2006-08-30 | 152 | +--------+-------+------------+-------+10 rows in set (0.00 sec) mysql> select * from driver_log order by field(name,'Suzi','Ben') desc;+--------+-------+------------+-------+ | rec_id | name | trav_date | miles | +--------+-------+------------+-------+ | 1 | Ben | 2006-08-30 | 152 | | 9 | Ben | 2006-09-02 | 79 | | 5 | Ben | 2006-08-29 | 131 | | 2 | Suzi | 2006-08-29 | 391 | | 7 | Suzi | 2006-09-02 | 502 | | 8 | Henry | 2006-09-01 | 197 | | 6 | Henry | 2006-08-26 | 115 | | 4 | Henry | 2006-08-27 | 96 | | 3 | Henry | 2006-08-29 | 300 | | 10 | Henry | 2006-08-30 | 203 | +--------+-------+------------+-------+10 rows in set (0.00 sec)

20180911更新內容:

我們都非常習慣通過 MySQL 的 IN 函數來查詢特定集合的數據,比如為了在 books 表中找出李雷、韓梅梅和安華寫的書,我們可以有如下的 SQL:

SELECT * FROM books WHERE `books`.`author` IN ('李雷','韓梅梅','安華');

數據庫返回如下結果:

authortitle
安華暴走漫畫
李雷藍色生死戀
韓梅梅冰與火之歌
韓梅梅天國的階梯
李雷這個殺手不太冷
韓梅梅阿甘正傳

雖然這樣確實能夠返回所有李雷、韓梅梅和安華寫過的書,但是返回的數據的排序方式是默認按照數據在數據庫中的存儲順序,假如我們需要的返回結果是同時按照 IN 查詢條件里邊的參數順序來排序呢?這個時候我們就需要利用到 MySQL FIELD 這個函數了,FIELD 函數本來是 MySQL 提供用來查詢某一個字符串在給定字符串元組中的索引位置的,比如這個官方例子:

SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo'); # -> 2

如果將其應用在 ORDER BY 排序條件中,就可以根據指定字段的值在給定參數列表中的索引數值,進而將查詢結果按照參數列表排序了

SELECT * FROM books WHERE `books`.`author` IN ('李雷','韓梅梅','安華') ORDER BY FIELD(author, '李雷','韓梅梅','安華'); authortitle
李雷藍色生死戀
李雷這個殺手不太冷
韓梅梅冰與火之歌
韓梅梅天國的階梯
韓梅梅阿甘正傳
安華暴走漫畫

可以發現,這一次,我們得到的結果就是按照條件參數列表 ‘李雷’,’韓梅梅’,’安華’ 進行排序后得到了。

應用層面的思考

1. 兼容性
本文提到的 FIELD 函數,畢竟只是 MySQL 數據庫內置提供的一種函數,除非你非常明確你的項目就是只用 MySQL 數據庫,否則,你的 SQL 代碼在未來遷移到其他數據庫的過程中就會遇到語法兼容性問題(只是 PostgreSQL 數據庫不支持 FIELD)。

2. 性能問題
我們都知道,數據庫在進行 ORDER BY 排序的時候,除非它是按照某個已經存在索引的鍵的值進行排序,否則數據庫則需要通過計算 ORDER BY 中表達式的值并且按照查詢結果建立新的臨時表,這個過程會帶來額外的時間開銷跟內存開銷,對數據庫本身就是一種性能負擔。這樣的方式在單一數據庫多個數據庫客戶端連接的時候,可能對數據庫造成太大負擔。

3. 與應用層代碼的結合
盡管使用 FIELD 函數可能帶來兼容性以及性能方面的隱患,但是 FIELD 的使用并非全是有損之處。

比如在與 Ruby 的 active_record 結合時,這種通過數據庫直接完成排序等 SQL 語句可以方便我們構建 ActiveRecord::Relation 對象,因為我們不再需要先將查詢結果集從內存中轉為數組排序,再進行二次查詢,可以幫助我們減少 N+1 查詢問題,后者也是常見的影響數據庫服務器性能的現象之一。除此之外,這樣的寫法也可以有效地幫助我們簡化代碼,保持代碼簡潔。

但是在不需要對數據進行二次查詢或者查詢數據量太大的情況下,我反而建議可以通過 Ruby 的 Array#sort_by 方法對數據進行排序,這樣的話,排序的任務就轉移給了客戶端代碼,排序任務的壓力就自然分散,減輕了服務器端的壓力。

總結

  • FIELD 函數結合 ORDER BY 可以幫助我們將查詢結果集按照參數列表順序返回;
  • FIELD 函數結合 ORDER BY 的方式可以幫助我們在數據庫層面完成排序,簡化了業務代碼邏輯;
  • FIELD 函數結合 ORDER BY 可能帶來 SQL 兼容性以及性能方面的問題;
    在確認項目數據庫不大可能為 MySQL 之外的數據庫的前提下,查詢數據量少或者需要保持業務代碼簡潔的場景下,我建議可以采用 FIELD 函數排序;而在數據量龐大的情況下,或者不大可能出現大量 N+1 查詢的情況下,我建議可以采用先在數據庫中查詢數據集(只查詢 IN 條件,不排序)再到內存中通過業務代碼排序(比如 Ruby 的 Array#sort_by)的方式。
  • 總結

    以上是生活随笔為你收集整理的MySQL自定义排序函数FIELD()的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。