SQLでのレコードのソートにはORDER BY
句を利用します。ORDER BYには複数の値を記述でき、値が同じ場合は2番目のフィールドの値でソートできます。
詳しくはこちらの記事を参照してください。
通常はORDER BYでのソートで十分ですが、利用シーンによってはより複雑なソートを実装したい場合があります。
この記事では、フィールドの値によってソートの条件を変えるSQL文を紹介します。
ORDER BY (フィールド1),(フィールド2), ...
CASE
WHEN (条件1) THEN (フィールド名 or 値)
WHEN (条件2) THEN (フィールド名 or 値)
...
ELSE (フィールド名 or 値)
END
以下のテーブルがあります。
id | code | name | grade | price | stock |
---|---|---|---|---|---|
1 | T-002 | ましかくテーブル | 1 | 85000 | 4 |
2 | C-003 | おしゃれなチェア | 2 | 255000 | 2 |
3 | S-010 | かるがる棚 | 1 | 8500 | 12 |
4 | S-024 | ウォールナット棚 | 2 | 99800 | 4 |
5 | T-080 | メープルテーブル | 2 | 384000 | 1 |
6 | S-401 | ロングテレビ台 | 2 | 198000 | 3 |
7 | C-011 | シンプルダイニングチェア | 1 | 29800 | 16 |
8 | T-011 | シンプルダイニングテーブル | 1 | 45000 | 4 |
9 | C-801 | コンフォートぺんぎんチェア | 2 | 1285000 | 1 |
10 | S-021 | チェリーキャビネット | 1 | 54000 | 5 |
このテーブルでpriceの値でソートしますが、gradeが1のものは価格(price)で昇順、gradeが2のものは価格(price)で降順にソートしたいです。
この場合、次のSQLを実行します。
SELECT * FROM ProductsG ORDER BY grade,
CASE
WHEN grade=1 THEN price
WHEN grade=2 THEN -price
ELSE price
END
grade=1 の場合はpriceの昇順にソートするため THEN にはprice を記述します。
grade=2 の場合はpriceの降順にソートするため、THEN には -price を記述し逆順にソートします。
それ以外のgradeの場合はpriceの昇順にソートする仕様(THEN price)としています。
結果は以下になります。
id | code | name | grade | price | stock |
---|---|---|---|---|---|
3 | S-010 | かるがる棚 | 1 | 8500 | 12 |
7 | C-011 | シンプルダイニングチェア | 1 | 29800 | 16 |
8 | T-011 | シンプルダイニングテーブル | 1 | 45000 | 4 |
10 | S-021 | チェリーキャビネット | 1 | 54000 | 5 |
1 | T-002 | ましかくテーブル | 1 | 85000 | 4 |
9 | C-801 | コンフォートぺんぎんチェア | 2 | 1285000 | 1 |
5 | T-080 | メープルテーブル | 2 | 384000 | 1 |
2 | C-003 | おしゃれなチェア | 2 | 255000 | 2 |
6 | S-401 | ロングテレビ台 | 2 | 198000 | 3 |
4 | S-024 | ウォールナット棚 | 2 | 99800 | 4 |
-
を使いたくない場合は以下の記述のSQLでも同じ結果になります。
gradeが1の場合はprice でソートし、gradeが2の場合は price DESC でソートし、それ以外の場合は priceでソートします。
SELECT * FROM ProductsG ORDER BY grade,
CASE WHEN grade=1 THEN price END,
CASE WHEN grade=2 THEN price END DESC,
CASE WHEN grade>2 THEN price END