昨天遇到一個奇葩的order 排序問題,不過真讓我大開眼界:
查詢Students表, 對Gender字段進行排序。(Gender類型修改為smallint,允許值0-3)
要求: Gender=1優先排序,其余按照出生日期:Birthday降序排列
常用的只有 order by col-name [asc/desc]. 優先排序,這不是非要在order中插入條件判斷,怎么可能?? But Nothing is Impossible!
1、插入測試數據:(DataAdd 參考: http://technet.microsoft.com/zh-cn/library/ms186819.aspx)
1 -- Insert some samples 2 --select FLOOR(RAND()*10) -- a random number, ranging from 0 to 9 3 Declare @randNum varchar(1), @date varchar(10) 4 Set @randNum = FLOOR(RAND()*10) 5 Set @date = '199' + @randNum + '-01-01' 6 7 insert into Students 8 values('Tom_'+@randNum, FLOOR(RAND()*4) ,DATEADD(m, FLOOR(RAND()*10) + 1,@date)) 9 go 50
2、自定義order by 條件判斷實現排序:(參考: http://www.tutorialspoint.com/sql/sql-sorting-results.htm)
1 select * from Students 2 order by (Case Gender When 1 Then 0 Else 1 End) asc, Birthday desc
數據顯示為:
結果剛剛好。雖然符合了需求,但第一次這樣用,萬分不理解。條件指定為0,1就可以,那其他的數字呢,還是說有什么默認的限制?經過不斷的測試,算是有點小眉目啦。
Order by 中的 Case 語句,相當於是自定義排序的實現方法。 用’冒泡’想想,就很容易理解了。
如果要實現升序排列,兩個數的比較,越小的,排列的位置越靠前,所以只需要給優先排序的字段最低的’權值’, 其他的依次排列。
同理就可以實現新的需求: Gender=1 優先, 3 其次, 其他 Birth 降序
1 select * from Students 2 order by ( 3 Case Gender -- set the priority: (asc - lower) 4 When 1 Then -1 5 When 3 Then 1 6 Else 2 7 End) asc, Birthday desc
當時又突然冒出了另一個問題,直接用order by num. 是個什么效果?恕我孤陋寡聞,以前真的不知道還有 order by [col-index], 現在才明白數字是列索引, 可以在一般意義上等價於列名稱。
參考:http://www.cnblogs.com/cuimingda/archive/2007/04/10/707237.html
[既然把多行給union了,把每列叫成什么名字都是不妥當的。。。只要采用列的序號即可, 序號從1開始。]
參考: http://technet.microsoft.com/zh-c·n/library/ms188723(v=sql.105).aspx
[如果列名已在 SELECT 列表中有了別名,則 ORDER BY 子句中只能使用別名。]
1 select StuID, StuName, Gender as Sex from Students 2 order by Sex -- equal to col index: 3 or the original col : Gender
但下面的這個,使用列名做為排序條件,仍然可以查詢?
1 select StuID, StuName from Students -- ok, the right data 2 order by Birthday desc 3 4 select * from Students 5 order by Birthday desc 6 7 --select StuID, StuName from Students 8 --order by 4 desc --- Error: ORDER BY 位置號 4 超出了選擇列表中項數的范圍
后來后來才找到真正重量級的解釋:http://msdn.microsoft.com/en-us/library/e9zc0283(v=vs.80).aspx