MYSQL ソートで対象の欄が空欄だったら、別の欄を使用してソートする

MYSQLなどデータベースの強みに「ソート」があります。
データ入力順だけでなく、あいうえお順、日付順、昇順、降順など条件に合わせてソートできます。

ところが今回次のようなソート条件が必要になりました。

基本はTO日付でソートだが、NULLの場合はFROM日付を参照する

えっ?別メンバ比較でソート?

そんなことが可能なの?

と思いましたが、いつものごとくググってググって対応することができました。
忘備録として記録いたします。

今回やりたいこと

イベントスケジュールの表示で、「早く終了するイベント順にソートする」という仕様が盛り込まれました。

イベント日付は、開催日(from 日付)/終了日(to 日付)があり、終了日を省略すると1日のみのイベントという意味になります。

つまりto日付がNULLならば、from日付を参照して終了日判定をしなければいけないのです。

とりあえずやってみたけど案の定うまくいきません

とりあえず以下のような普通の指定をやってみました。
が、案の定うまくいきませんでした。

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文ににています。

まずはその記述方法を以下に記載します。

TO日付がNULLならば、FROM日付を使用するように条件を設定しました。
これで動くの?
と半信半疑でしたが、以下のようにちゃんと動作しました。

ORDER BY句でも条件分岐が動くんだと、改めて知りました。
無理だと思ってもやってみるものです。

記述についての注意点

今回TO日付がNULLかどうかを判定するのに、「to_date IS null」と記述しています。
xamppだとこの記述で動作しましたが、実機サーバーでテストしたところ文法エラーになりました。

日付にNULL指定はありえませんエラーでした。

どうやらサーバーによっては日付にNULLが入らないケースがあるようでした。
そこで次のような記述に変えたらうまくいきました。

NULLを’0000-00-00’に変えたら省略されているか判定できました。
日付の保存状態については、サーバーにより異なるためNULLでうまくいかない場合は別の記述をする必要があります。

MYSQLは思ったより柔軟

データベースはデータの入出力を行う代物です。
原則、データの読み書きする機能しかありません。

そのため、プログラム的な要素は無いように思われがちです。
でもいろいろやってみると、思ったよりもロジックを組み込むことができました。

様々な条件を付けることで、難易度の高い表示方法も実現できます。

今回は自身のスキルを上げることができた事例でした。

今回のレポートは以上です。
読んでいただいてありがとうございました。


ホームページに関するお悩み事やご相談事がございましたら私どもまでご連絡ください。 鋭意ご対応申し上げます。
ホームページのご提案もさせていただいております