Mysql

MySQL中的ORDER BY FIELD()如何在內部工作

  • September 18, 2021

我了解ORDER BY子句的工作原理以及FIELD()功能的工作原理。我想了解的是他們兩個如何一起工作來排序。如何檢索行以及如何得出排序順序

+----+---------+
| id |  name   |
+----+---------+
|  1 | stan    |
|  2 | kyle    |
|  3 | kenny   |
|  4 | cartman |
+----+---------+ 

SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)

上面的查詢將導致

+----+---------+
| id |  name   |
+----+---------+
|  3 | kenny   |
|  2 | kyle    |
|  1 | stan    |
|  4 | cartman |
+----+---------+ 

類似於說 ORDER BY 3, 2, 1, 4 的東西

問題

  • 這在內部如何運作?
  • MySQL如何獲取行,併計算排序順序?
  • MySQL 如何知道它必須按 id 列排序?

作為記錄

SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);

應該也可以,因為您不必在WHERE子句中對列表進行排序

至於它是如何運作的,

  • FIELD()是一個函式,如果您要搜尋的值存在,則返回逗號分隔列表的索引位置。

  • 這些ORDER BY值由FIELD()返回的值評估

您可以創建各種花哨的訂單

例如,使用IF()函式

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0),FIELD(id,3,2,1,4);

這將導致前 4 個 id 出現在列表的頂部,否則,它會出現在底部。為什麼?

在 中ORDER BY,您得到 0 或 1。

  • 如果第一列為 0,則使前 4 個 id 中的任何一個出現
  • 如果第一列是 1,讓它在後面出現

讓我們在第一列用 DESC 翻轉它

SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0) DESC,FIELD(id,3,2,1,4);

在 中ORDER BY,您仍然得到 0 或 1。

  • 如果第一列為 1,則顯示除前 4 個 id 之外的任何內容。
  • 如果第一列為0,則使前4個id按原順序出現

您的實際問題

如果您真的想了解這方面的內部資訊,請轉到本書的第 189 頁和第 192 頁

MySQL 內部結構

進行真正的深潛。

本質上,有一個名為ORDER *orderORDER BY表達式樹)的 C++ 類。在JOIN::prepare,*order中使用了一個名為 的函式setup_order()為什麼在JOIN課堂中間? 每個查詢,甚至是針對單個表的查詢都始終作為 JOIN 處理(請參閱我的文章JOIN 條件和 WHERE 條件之間存在執行差異嗎?

這一切的原始碼是sql/sql_select.cc

顯然,這ORDER BY棵樹將持有 的評估FIELD(id,3,2,1,4)。因此,數字 0,1,2,3,4 是被排序的值,同時攜帶對所涉及行的引用。

引用自:https://dba.stackexchange.com/questions/109120