Archive | MySQL RSS feed for this section

OracleのADD_MONTHSをMySQLのDATE_ADDに置き換えるとき気をつけること このエントリーをはてなブックマークに追加

25 8月

OracleのADD_MONTHSで月を加算する際、加算対象日がその月の最終日だったら、加算後の日も最終日になる。
だから、単純にMySQLに移行しDATE_ADDに置き換えるとき、最終日が意味を持つのか?ということはよく考えなくてはならない。

<Oracle>

ADD_MONTHS('2012-02-29', 1) => 2012-03-31

<MySQL>

DATE_ADD('2012-02-29', INTERVAL 1 MONTH) => 2012-03-29

MySQLのほうが素直な気がする。
なので、MySQLでも同様に最終日だったら1月加算しても最終日にする、という動きにしたい場合、ストアドファンクションなりプログラム側でうまいこと値を渡してやるなりしないと大変だね。というはなしです。

MySQLでNULLもイコールする このエントリーをはてなブックマークに追加

24 8月

普通、NULLのカラムを取るのには

SELECT * FROM table WHERE column IS NULL;

のようにして、IS NULLを使うけれども、演算子 <=>を使うとNULL対応の=と同じになる!

SELECT 1 &lt;=&gt; 1          -&gt;    1
SELECT 1 &lt;=&gt; 3          -&gt;    0
SELECT 1 &lt;=&gt; NULL       -&gt;    0
SELECT NULL &lt;=&gt; NULL    -&gt;    1

hogehoge IS NULL も簡単にかける。

ISNULL(hogehoge)

ほおぁぁ・・・・。書き換えます。

MySQLでNULLを下にASCソートする このエントリーをはてなブックマークに追加

24 8月

前のブログを削除する予定なので、こちらに移動。

ソートするとNULLがDBMS依存でソートされる問題

こういうテーブルがあります。これはidの順にソートしてます。

SELECT * FROM table ORDER BY id
id name
1 Hitomi
2 Shida
3 NULL

これを、nameの順にソートすると

SELECT * FROM table ORDER BY name
id name
3 NULL
1 Hitomi
2 Shida

こうなります。NULLが最大値と解釈されているためです。Oracleだと最小値と解釈され、一番下にきます。NULLをどうソートするかはDBMS依存のようです。

現在のまとめ

  • NULLをどうソートするかはDBMS依存
  • MySQLではNULLが最大値と解釈されてソートされる
  • OracleではNULLが最小値と解釈されてソートされる

MySQL4系:NULLを後ろにするにはCASE文を使う

昇順ソートでNULLを後ろに持ってきたいとき、MySQL4系では

ORDER BY CASE WHEN column_name IS NULL 最低値 ELSE column_name END

こうすると、column_nameの値がNULLだったとき最低値が入った状態でソートされる

(name_kanaがNULLか空文字だったとき、カナの最低値であるヴヴヴヴを入れて強制的にソート順ASCの一番下にする)

SELECT *
FROM table
ORDER BY CASE
WHEN name_kana IS NULL OR name = '' THEN 'ヴヴヴヴヴ'
ELSE name_kana END

MySQL5系:NULLを最後にするにはIS NULLをORDER BYに

MySQL5系では、IS NULLをORDER BYに入れることでNULLを最後にできる(でも、DBMSの系がわからないなら4系のほうがエラー起きなくていいのかも。)

ORDER BY column_name IS NULL, column_name;

Oracle:NULLをLAST・FIRSTに切り替えられる

ORACLEだとNULLは最大値扱いで、下記クエリはNULLをLASTにしたりFIRSTにしたりできる(便利ね)

ORDER BY column_name NULLS LAST;

例:MySQL5でCASEを使って県名ソートする

例えば、県名が直接DBに入っていて、都道府県順にソートできない〜〜といったときにも使えます。

SELECT *
FROM table
ORDER BY
CASE
WHEN m.org_address_1 = '北海道' THEN 1
WHEN m.org_address_1 = '青森県' THEN 2
...

なんかこうしたら北海道って入ってたら1とみなされてソートするからいいんじゃないかなと。
そもそもそんなテーブルいやだけど…