web-dev-qa-db-ja.com

SQL ORDER BY複数の値を特定の順序で?

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を使用して渡された値を検証できます。

私にできないこと:

  • GROUP BY、特定のレコード値を返す必要があるため
  • WHERE x_field IN( 'f'、 'p'、 'i'、 'a')、いくつかの検証テストに1つのクエリを使用しようとしているため、すべての値が必要です。また、x_field値はDESC/ASCの順序ではありません

この質問を書いた後、私はこれを再考する必要があると思い始めています、LOL!

74
Phill Pafford
...
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
147
gbn

「VALUES( 'f'、1)、( 'p'、2)、( 'a'、3)、( 'i'、4)」でLEFT JOINを使用し、注文の2列目を使用できます表現による。 Postgresは、多くの値がある場合、巨大なCASEよりもはるかに高速なハッシュ結合を使用します。また、自動生成が簡単です。

この順序情報が修正される場合、独自のテーブルが必要です。

24
peufeu

試してください:

ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'

あなたは正しい軌道に乗っていましたが、F値にのみx_fieldを置くことで、他の3つは定数として扱われ、データセット内の何とも比較されませんでした。

19
Marc B

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
12
Guffa

私はこれのためにもっときれいな解決策を見つけました:

ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)

注:array_positionにはPostgres v9.5以降が必要です。

6
rept

CASEおよびORDER BYの提案はすべて機能するはずですが、別の色の馬を提案します。 x_fieldの妥当な数の値のみがあり、それらの値がすでにわかっていると仮定して、F、P、A、およびIを値とする 列挙型 を作成します。他の可能な値が適用されます)。列挙型は、CREATEステートメントで示される順序で並べ替えられます。また、実際のアプリケーションではおそらく意味のある値の名前を使用できますが、序数の位置のみが保存されるため、スペースを無駄にせずに機密性を保護できます。

6
Andrew Lazarus

選択した列または他の式で並べ替えることができます。

ここに、ケースステートメントの結果で並べ替える方法の例:

  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
0
JIYAUL MUSTAPHA