Monday 16 July 2018

How does ORDER BY FIELD() in MySQL work internally

How does ORDER BY FIELD() in MySQL work internally



I understand how ORDER BY clause works and how the FIELD() function works. What i want to understand is how the both of them work together to sort. How are the rows retrieved and how is the sort order derived
+----+---------+
| 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)
The query above will result in
+----+---------+
| id |  name   |
+----+---------+
|  3 | kenny   |
|  2 | kyle    |
|  1 | stan    |
|  4 | cartman |
+----+---------+ 
something similar to saying ORDER BY 3, 2, 1, 4
QUESTIONS
  • How does this work internally?
  • How does MySQL get the rows, and calculate the sort order ?
  • How does MySQL know it has to sort by the id column ?

39down voteaccepted
For the record
SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);
should work as well because you do not have to order the list in the WHERE clause
As for how it works,
  • FIELD() is a function that returns the index position of a comma-delimited list if the value you are searching for exists.
  • The ORDER BY values are evaluated by what FIELD() returns
You can create all sorts of fancy orders
For example, using the IF() function
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);
This will cause the first 4 ids to appear at the top of the list, Otherwise, it appears at the bottom. Why?
In the ORDER BY, you either get 0 or 1.
  • If the first column is 0, make any of the first 4 ids appear
  • If the first column is 1, make it appear afterwards
Let's flip it with DESC in the first column
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);
In the ORDER BY, you still either get 0 or 1.
  • If the first column is 1, make anything but the first 4 ids appear.
  • If the first column is 0, make the first 4 ids appear in the original order

0 comments:

Post a Comment