OKインデックス付きキーと非インデックス付きフィールドを持つテーブルがあります。特定の値を持つすべてのレコードを見つけて行を返す必要があります。複数の値で注文できるかどうか知りたいのですが。
例:
id x_field
-- -----
123 a
124 a
125 a
126 b
127 f
128 b
129 a
130 x
131 x
132 b
133 p
134 p
135 i
pseudo:結果を次のように並べる場合は、where ORDER BY x_field = 'f', 'p', 'i', 'a'
SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'
結果は次のようになります。
id x_field
-- -----
127 f
133 p
134 p
135 i
123 a
124 a
125 a
129 a
構文は有効ですが、クエリを実行すると、レコードを1レコードに制限しても、結果が返されることはありません。これについて別の方法がありますか?
X_fieldをテスト結果と考え、条件に該当するすべてのレコードを検証する必要があります。失敗した値、合格した値の順にテスト結果を並べたいと思いました。したがって、最初に失敗した値を検証し、次にORDER BYを使用して渡された値を検証できます。
私にできないこと:
この質問を書いた後、私はこれを再考する必要があると思い始めています、LOL!
...
WHERE
x_field IN ('f', 'p', 'i', 'a') ...
ORDER BY
CASE x_field
WHEN 'f' THEN 1
WHEN 'p' THEN 2
WHEN 'i' THEN 3
WHEN 'a' THEN 4
ELSE 5 --needed only is no IN clause above. eg when = 'b'
END, id
「VALUES( 'f'、1)、( 'p'、2)、( 'a'、3)、( 'i'、4)」でLEFT JOINを使用し、注文の2列目を使用できます表現による。 Postgresは、多くの値がある場合、巨大なCASEよりもはるかに高速なハッシュ結合を使用します。また、自動生成が簡単です。
この順序情報が修正される場合、独自のテーブルが必要です。
試してください:
ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'
あなたは正しい軌道に乗っていましたが、F値にのみx_fieldを置くことで、他の3つは定数として扱われ、データセット内の何とも比較されませんでした。
case
スイッチを使用して、コードをソート可能な数値に変換します。
ORDER BY
case x_field
when 'f' then 1
when 'p' then 2
when 'i' then 3
when 'a' then 4
else 5
end
私はこれのためにもっときれいな解決策を見つけました:
ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)
注:array_positionにはPostgres v9.5以降が必要です。
CASE
およびORDER BY
の提案はすべて機能するはずですが、別の色の馬を提案します。 x_field
の妥当な数の値のみがあり、それらの値がすでにわかっていると仮定して、F、P、A、およびIを値とする 列挙型 を作成します。他の可能な値が適用されます)。列挙型は、CREATE
ステートメントで示される順序で並べ替えられます。また、実際のアプリケーションではおそらく意味のある値の名前を使用できますが、序数の位置のみが保存されるため、スペースを無駄にせずに機密性を保護できます。
選択した列または他の式で並べ替えることができます。
ここに、ケースステートメントの結果で並べ替える方法の例:
SELECT col1
, col2
FROM tbl_Bill
WHERE col1 = 0
ORDER BY -- order by case-statement
CASE WHEN tbl_Bill.IsGen = 0 THEN 0
WHEN tbl_Bill.IsGen = 1 THEN 1
ELSE 2 END
結果は、「IsGen = 0」行で始まり、「IsGen = 1」行と他のすべての行が最後に続くリストになります。
最後にさらに注文パラメーターを追加できます。
SELECT col1
, col2
FROM tbl_Bill
WHERE col1 = 0
ORDER BY -- order by case-statement
CASE WHEN tbl_Bill.IsGen = 0 THEN 0
WHEN tbl_Bill.IsGen = 1 THEN 1
ELSE 2 END,
col1,
col2