自定义ORDER BY说明

时间:2010-11-03 15:12:11

标签: postgresql sql-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放在第一位,但它没有,它把它放在最后。我想我的问题是:为什么我必须使用!=,而不是在这种情况下?

4 个答案:

答案 0 :(得分:51)

每个表达式都被评估为bool,并将其视为0表示false,1表示true表示并适当排序。即使这有效,但逻辑很难遵循(并因此维持)。我使用的是一个在数组中查找值索引的函数。

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

这更容易理解。钉子将先排序,坚果排序。您可以在Postgres代码段存储库中查看如何创建idx函数。 http://wiki.postgresql.org/wiki/Array_Index

答案 1 :(得分:36)

我从未见过它,但似乎有道理。

首先按s.type != 'Nails'排序。对于false列中包含Nails的每一行,typeBolts。之后,它按Bolts排序。同样,对于包含type作为false的所有列,此计算结果为false。等等。

小型测试显示在true之前订购了Nails。因此,您拥有以下内容:首先,您将获得ORDER BY的所有行,因为评估为falsefalse的相应ORDER BY位于第一位。其余行按第二个{{1}}条件排序。等等。

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

答案 2 :(得分:34)

@Scott Bailey提出了很棒的主意。但是自PostgreSQL 9.5以来它可以更简单(你不必创建自定义函数)。只需使用array_position功能:

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

答案 3 :(得分:5)

使用array_position,它需要具有您要查询的相同类型。

e.g:

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