postgresql 自定义ORDER BY说明

s6fujrry  于 2022-12-03  发布在  PostgreSQL
关注(0)|答案(5)|浏览(315)

前段时间发现了这个,从那以后一直在用;但是今天看了,我发现我并不完全理解它为什么有效,有人能给我解释一下吗?

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

如果我按类型排序,它是按字母顺序排序的。如果我使用上面的例子,它使用与行位置相同的顺序。我不明白的是!=的使用。如果我使用=,它会以相反的顺序出现。我无法理解这个概念。
我认为用“=”代替上面的“!=”会把“钉子”放在第一个位置,但事实并非如此,它会把“钉子”放在最后一个位置。我想我的问题是:在这种情况下,为什么我必须使用!=,而不是=?

lc8prwob

lc8prwob1#

@Scott Bailey提出了一个好主意。但是自从PostgreSQL 9.5以来,它可以更简单(你不必创建自定义函数)。只需使用array_position函数:

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

4jb9z9bj2#

每一个表达式都被当作布尔值来计算,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

1u4esq0p

1u4esq0p3#

我从来没见过,但它似乎是有道理的。
首先,它按s.type != 'Nails'排序,对于type列中包含Nails的每一行,它都是false,之后,它按Bolts排序,对于所有包含Bolts的列,它的值都是false,依此类推。
一个小的测试显示false的顺序在true之前。首先,您会得到所有Nails在最上面的行,因为计算结果为falsefalse的相应ORDER BY排在最前面。其余行按第二个ORDER BY标准排序,依此类推。

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

kxeu7u2r4#

使用array_position时,它的类型必须与查询的类型相同。
例如:

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

lb3vh1jj5#

这是按给定的值列表排序
从Postgres 9.4开始,一个干净的解决方案是LEFT JOIN到一个非嵌套数组WITH ORDINALITYORDER BY得到序数:

SELECT ...
FROM   ...
LEFT   JOIN unnest ('{Nails,Bolts,Washers,Screws,Staples,Nuts}'::text[]) WITH ORDINALITY sort(type, ord) USING (type)
ORDER  BY sort.ord ...

fiddle
请参阅:

  • ORDER BY IN值列表

相关问题