2010-11-03 79 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);