web-dev-qa-db-ja.com

カスタムORDER BY説明

私はこれを少し前に見つけ、それを使っています。しかし、今日それを見ると、なぜそれが機能するのか完全に理解していないことに気付きました。誰かが私にそれについていくつかの光を当てることができますか?

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

S.typeで注文するとアルファベット順になります。上記の例を使用すると、行の位置と同じ順序が使用されます。私が理解していないのは、!=の使用です。 =を使用すると、逆の順序で表示されます。私はこの概念に頭を抱えることはできません。

上記の!=の代わりに=を使用すると、釘が最初に配置されますが、そうではなく、最後に配置されます。私の質問はこれだと思います:なぜこの状況で=ではなく!=を使用する必要があるのですか?

57
Evil Elf

見たことがありませんが、理にかなっているようです。

最初はs.type != 'Nails'で注文します。これは、false列にNailsを含むすべての行のtypeです。その後、Boltsでソートされます。 Boltstypeとして含むすべての列について、これはfalseと評価されます。等々。

小さなテストでは、falsetrueの前に並べられていることがわかります。したがって、次のようになります。まず、Nailsfalseに評価されたORDER BYが最初に来るため、falseが上にあるすべての行を取得します。残りの行は、2番目のORDER BY基準でソートされます。等々。

タイプ| !=ネイル| !=ボルト| !=ワッシャー
 '釘' |誤り|真| true 
「ボルト」|真|誤り| true 
 'ワッシャー' |真|真| false 
36
musiKk

各式はブール値として評価され、falseの場合は0、trueの場合は1として扱われ、適切にソートされます。これは機能しますが、ロジックは従うのが難しいため、維持することはできません。私が使用しているのは、配列内の値のインデックスを見つける関数です。

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

これは従う方がはるかに簡単です。釘は最初にソートされ、ナットは最後にソートされます。 Postgresスニペットリポジトリでidx関数を作成する方法を確認できます。 http://wiki.postgresql.org/wiki/Array_Index

51
Scott Bailey

@ Scott Bailey は素晴らしいアイデアを提案しました。しかし、PostgreSQL 9.5以降では、もっと簡単にできます(カスタム関数を作成する必要はありません)。 array_position 関数:

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

array_positionでは、クエリ対象と同じ型である必要があります。

例えば:

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