Mysql
MySQL中的ORDER BY FIELD()如何在內部工作
我了解
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()是一個函式,如果您要搜尋的值存在,則返回逗號分隔列表的索引位置。
- 如果 id = 1,則FIELD(id,3,2,1,4)返回 3(1 在列表中的位置)
- 如果 id = 2,則FIELD(id,3,2,1,4)返回 2(2 在列表中的位置)
- 如果 id = 3,則FIELD(id,3,2,1,4)返回 1(3 在列表中的位置)
- 如果 id = 4,則FIELD(id,3,2,1,4)返回 4(4 在列表中的位置)
- 如果 id = 其他任何內容,則FIELD(id,3,2,1,4)返回 0(不在列表中)
這些
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 頁
進行真正的深潛。
本質上,有一個名為
ORDER *order
(ORDER 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 是被排序的值,同時攜帶對所涉及行的引用。