MYSQLなどデータベースの強みに「ソート」があります。
データ入力順だけでなく、あいうえお順、日付順、昇順、降順など条件に合わせてソートできます。
ところが今回次のようなソート条件が必要になりました。
基本はTO日付でソートだが、NULLの場合はFROM日付を参照する
えっ?別メンバ比較でソート?
そんなことが可能なの?
と思いましたが、いつものごとくググってググって対応することができました。
忘備録として記録いたします。
今回やりたいこと
イベントスケジュールの表示で、「早く終了するイベント順にソートする」という仕様が盛り込まれました。
イベント日付は、開催日(from 日付)/終了日(to 日付)があり、終了日を省略すると1日のみのイベントという意味になります。
つまりto日付がNULLならば、from日付を参照して終了日判定をしなければいけないのです。
とりあえずやってみたけど案の定うまくいきません
とりあえず以下のような普通の指定をやってみました。
が、案の定うまくいきませんでした。
SELECT * FROM date_sort ORDER BY to_date asc;
where句であれば、ANDやOR条件を駆使すれば開催前、開催中のイベントデータを容易に抽出できます。
しかしorder by句でAND やORを使用しても異なるメンバ名の比較はできません。
いったいどうやれば実現できるのか?
ググって調べてみました。
条件判断処理で複数のメンバ名を同時比較する
やりたいことは、TO日付がある場合はTO日付を使用し、TO日付がNULLの場合はFROM日付を使用するです。
その条件はTO日付がNULLかどうかです。
ということはIF文をつかえば実現できます。
「TO日付がNULLならばFROM日付を使用」という処理です。
ここで疑問がわきました。
order by 句でIF文つかえるの?
ORDER BY句で条件指定する記述
厳密にいうと、MYSQLではIF文が使えません。
ただし、条件分岐はできます。
それがCASE WHEN文です。
なんとなくPHPのSWITCH文ににています。
まずはその記述方法を以下に記載します。
SELECT * FROM date_sort ORDER BY case WHEN to_date IS null THEN from_date ELSE to_date END asc;
TO日付がNULLならば、FROM日付を使用するように条件を設定しました。
これで動くの?
と半信半疑でしたが、以下のようにちゃんと動作しました。
ORDER BY句でも条件分岐が動くんだと、改めて知りました。
無理だと思ってもやってみるものです。
記述についての注意点
今回TO日付がNULLかどうかを判定するのに、「to_date IS null」と記述しています。
xamppだとこの記述で動作しましたが、実機サーバーでテストしたところ文法エラーになりました。
日付にNULL指定はありえませんエラーでした。
どうやらサーバーによっては日付にNULLが入らないケースがあるようでした。
そこで次のような記述に変えたらうまくいきました。
CASE WHEN to_date IS NULL THEN ・・・
↓
CASE WHEN to_date = '0000-00-00' TEHN ・・・
NULLを’0000-00-00’に変えたら省略されているか判定できました。
日付の保存状態については、サーバーにより異なるためNULLでうまくいかない場合は別の記述をする必要があります。
MYSQLは思ったより柔軟
データベースはデータの入出力を行う代物です。
原則、データの読み書きする機能しかありません。
そのため、プログラム的な要素は無いように思われがちです。
でもいろいろやってみると、思ったよりもロジックを組み込むことができました。
様々な条件を付けることで、難易度の高い表示方法も実現できます。
今回は自身のスキルを上げることができた事例でした。