需求背景
在做商品管理的時候,碰到一個SQL的排序問題,需要把上架的商品排在下架商品之前。一番折騰后,搜索到了條件排序語句 order by if(),小編在此和大家分享一下。本文測試數據存在如下所示的表test中:
+----+------+
| id | type |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 3 |
| 8 | 4 |
| 9 | 4 |
| 10 | 4 |
+----+------+
使用 IF 語句
想要 type=3 的記錄排在前面,type為其他值的排在后面,可以這樣寫SQL:
SELECT * FROM test ORDER BY IF(type=3,0,1);
結果如下:
+----+------+
| id | type |
+----+------+
| 6 | 3 |
| 7 | 3 |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 8 | 4 |
| 9 | 4 |
| 10 | 4 |
+----+------+
解釋:IF(type=3,0,1)的意思是,對 type 附加一個隱藏屬性,這個隱藏屬性的值可以是0或者1;在對 type進行排序的時候,優先判斷type是不是等於3,如果等於,則返回0;否則,返回1。然后對type隱藏屬性進行排序,也就是對0和1進行排序。
總而言之,可以把IF語句視作一個獨立的字段,用於order by之后進行排序。假如想讓type=3的數據排在后面,就可以IF語句后面添加DESC了,如下:
SELECT * FROM test ORDER BY IF(type=3,0,1) DESC;
結果如下:
+----+------+
| id | type |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 8 | 4 |
| 9 | 4 |
| 10 | 4 |
| 6 | 3 |
| 7 | 3 |
+----+------+
另外,你在進行隱藏屬性優先排序的同時,對於剩下的排序,你也可以另外進行ASC或者DESC的排序
使用 IN 語句
上面的例子是滿足單個條件,返回0 或者 1,如果需要用到一個范圍呢?比如想讓 type =2或者type=3的行排在前面呢?可以使用 IN 語句
SELECT * FROM ORDER BY type IN (2,3) DESC
結果如下
+----+------+
| id | type |
+----+------+
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 3 |
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 8 | 4 |
| 9 | 4 |
| 10 | 4 |
+----+------+
下面分析語句type IN (2,3) DESC, type IN 語句進行判斷,如果type的值在(2,3)里面,返回1,否則返回0,所以,滿足條件的數據,因為返回值是1,進行DESC排序的時候,就被放在最后。
其他情況以此類推。好記性不如爛筆頭,因為平時用的時候只是用IN來篩選,很少遇到和排序相結合的場景,所以記錄一下。