問題(一):Order By 多個參數排序
在做多字段的排序的時候我們經常會會用到該語句。
所以多參數排序是從左到右的局部排序,修改的範圍只有前面參數(幾個參數)相同的情況下在排序。
select * from table order by 參數1 , 參數2 DESC …… limit ?
在做多字段的排序的時候我們經常會會用到該語句。
這裏的參數1 是按照 ASC 排序所以就可以省略,參數2 是按照DESC排序,由於
大多數 where 後面的過濾條件是從右到左,而Order by後面的順序應該怎麼的?
這裏的順序是從參數1,參數2這麼開始排序的,是從左到右。
比如:把參數1的排完,在排序參數2,但參數2的排序並非對參數1的數據重新排序,
而是對參數1相同的數據進行排序。
誤解:
很多人想得到100個最小的x,但想把這100個數據按照y從小到大的排序,於是就寫這樣
的SQL語句
select * from table x ASC,y DESC limit 100
這就是我們理解錯了,這裏的y只是對排好的x相同的數據進行排序,如果這100個數據x完全
不同,後面添加對y的排序時是沒有影響的。這裏只對x相同的數據進行局部的y排序。
變化如下:
1-2 1-2
2-1 2-3
2-3 2-1
3-4 3-4
……
所以多參數排序是從左到右的局部排序,修改的範圍只有前面參數(幾個參數)相同的情況下在排序。
比如:ORDER BY h.floor*1,convert(h.floor using gbk) asc
圖解:
問題(二):Order By 根據 IF 條件對字段進行排序
比如:ORDER BY IF(a.state = '1',0,1),a.update_date DESC
圖解:
同理可得:不同條件下都可以通過 IF 來對字段進行排序
【Oracle 結論】
order by colum asc 時,null默認被放在最後
order by colum desc 時,null默認被放在最前
nulls first 時,強制null放在最前,不爲null的按聲明順序[asc|desc]進行排序(select update_date from table_name order by update_date nulls first;)
nulls last 時,強制null放在最後,不爲null的按聲明順序[asc|desc]進行排序(select update_date from table_name order by update_date nulls last;)
【MySql 結論】
order by colum asc 時,null默認被放在最前
order by colum desc 時,null默認被放在最後
ORDER BY IF(ISNULL(update_date),0,1) null被強制放在最前,不爲null的按聲明順序[asc|desc]進行排序
ORDER BY IF(ISNULL(update_date),1,0) null被強制放在最後,不爲null的按聲明順序[asc|desc]進行排序
問題(三):Order By 字母數字混合字段排序問題
對MySQL數據表裏的一個字符型字段排序,其內容格式爲一位字母+順序數字。數字沒有前導零,長度不固定。
這種含字母的數字序列,排序出來的結果和我們想要的結果是不一樣的,因爲它不是純數字,只能按字符規則排。
結果是A1,A10,A11,A12。。。。A19,A2,A20,A21。。。。
而不是我們通常感覺中的A1,A2,A3,。。。。。A10,A11,這樣的結果。
想要得到正確的排序有兩個辦法。
一是改變字段內容結構,在數字前加上零,讓所有的字段值擁有相同的長度。
二是不改變字段內容,在排序的SQL語句上想辦法。
order by mid(column,2,10) +1
mid()第一個參數是字串內容,可以是字段名。第二個參數是起始字符的位置,我這裏需要從第二個字符開始。第三個參數是需要取得的長度,要選一個可以包含所有字段內容長度的值,寧大勿小。
但這樣取出來的還只是“數字內容的字符串”,對它排序仍然使用字符規則,不會得到我們想要的結果。
這時需要給這個結果再加上一個數值,讓MySQL對它進行一次算術運算,然後得到的就是一個整型值,這時再排序就是數字順序的結果了。
例如:
SELECT * FROM equipmentmes ORDER BY MID(eqid,2,10) +1