2010-11-03 161 views
31

我前一段時間發現並自此使用它;然而,今天看到它,我意識到我不完全明白它爲什麼起作用。有人能幫我解釋一下嗎?自定義ORDER BY說明

ORDER BY s.type!= 'Nails', 
      s.type!= 'Bolts', 
      s.type!= 'Washers', 
      s.type!= 'Screws', 
      s.type!= 'Staples', 
      s.type!= 'Nuts', ... 

如果我按s.type訂購,它按字母順序排列。如果我使用上面的示例,它使用與行位置相同的順序。我不明白的是使用!=。如果我使用=它出現在相反的順序。我無法圍繞這個概念包圍我的頭。

對我而言,使用=代替上面的!='會讓Nails第一位置,但它不會,它將它放在最後。我想我的問題是這樣的:爲什麼我必須使用!=,not =在這種情況下?

+14

所以,如果我不明白的東西,即使我喜歡一個解決方案的優雅和簡潔,我要握住我的手在我的耳朵,重複「啦,啦,啦」。我不喜歡這種方法;我寧願學習一些新的東西,並對此感到滿意。 – 2011-03-02 15:30:44

回答

23

我從來沒有見過它,但它似乎有道理。

起初它通過訂購s.type != 'Nails'。對於type列中包含Nails的每行,這是false。之後它按Bolts排序。再次對於包含Bolts的所有列作爲type,此評估爲錯誤。等等。

小測試顯示falsetrue之前訂購。所以你有以下幾點:首先你會得到所有排在Nails之上的行,因爲根據ORDER BY評估爲falsefalse最先。其餘行按第二個ORDER BY標準排序。等等。

 
type  | != Nails | != Bolts | != Washers 
'Nails' | false | true  | true 
'Bolts' | true  | false | true 
'Washers' | true  | true  | false 
+1

不要忘記NULL。 – 2010-11-03 15:48:41

+1

這完全是一個想法。但是我假設它在true之前命令false,因爲它們的推薦整數值爲0和1,其中0(false)在1(真)之前。 – 2013-08-19 17:53:22

41

每個表達式被評價爲一個bool和視爲0代表假,1代表真,並適當地排序。即使這有效,邏輯很難遵循(並因此保持)。我使用的是一個函數,它可以在數組中找到值的索引。

ORDER BY idx(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type) 

這更容易遵循。指甲將首先排序,最後排序爲堅果。您可以看到如何在Postgres代碼片段庫中創建idx函數。 http://wiki.postgresql.org/wiki/Array_Index

+2

應該是'array_position' – 2016-10-20 20:21:52

+1

@EbenGeer只有9.5以上 – DarkMukke 2017-05-22 12:54:22

15

@Scott Bailey建議的好主意。但從PostgreSQL 9.5開始,它可以更簡單(不必創建自定義函數)。只需使用array_position功能:

ORDER BY array_position(array['Nails','Bolts','Washers','Screws','Staples','Nuts'], s.type) 
+0

這個答案爲我節省了很多工作。謝謝! – 2017-02-08 11:01:03

+0

在我的開發實例上嘗試過,很棒,生產仍然在9.3 ..不是很好 – DarkMukke 2017-05-22 12:53:49

+2

這適用於'文本'類型的列,我試着用列類型'字符'和函數拋出一個錯誤 - 希望這有助於:) – 2017-09-07 03:41:18

1

與array_position,它需要有一個要查詢對同一類型。

如:

select array_position(array['foo'::char,'bar','baz'::char], 'bar'); 
select array_position(array['foo'::char,'bar','baz'::char], 'baz'::char);