MySQLのやつが!(日付型)
phpとMySQLを使ったシステムをいくつか作っているのですが、phpは言うに及ばず、MySQLも負けず劣らず、勝手な変換をしてくれちゃったりしちゃったりするわけなのです。でも厳密な書き方ってどうやるのか知らん。(いちいち型変換かますのは嫌です。)
ええと、日付型の比較の話なのですが「yyyy/mm/dd」という編集形式で入力された日付を条件に、データを引っ張ってきたいのです。
名称:TblWork
日付の列:Date1(date型)
というテーブルがあると思ってください。ちなみに、MySQLのバージョンは5.1.6です。
日付の列に「2012年11月20日」がセットされているデータが1件あります。
phpからpdoを使って、日付を条件としたSQL文を投げます。
条件はプレースホルダを使って指定します。「:cndDate」には「’2012/11/20’」をセットしています。
日付は本当は「yyyy-mm-dd」で指定したいところですが、とりあえずめんどかったのでそのままです。(だっていつもそれで検索してくれるから…。)今回も適当に検索してくれると思いきや。これがなぜだか上手くいかないのでした。
もしかして、「mm/dd/yyyy」なの?と思って「2020/12/11」とか「2020/11/12」とかもデータに追加してみたのですが、それらもヒットせず。
以下、色々試したのでその結果。ヒットするものを○、しないものを×としました。
(1) そのまま条件にする → ○
SELECT * FROM `TblWork` WHERE `Date1` = :cndDate;
(2) IFNULL関数を使う → ×
SELECT * FROM `TblWork` WHERE IFNULL(`Date1`, ‘2012-11-20’) = :cndDate;
日付がNULLの場合は、無条件に該当させたかったのですが、これがなぜだか上手くいかず。
(3) IFNULL関数を使う(その2) → ×
SELECT * FROM `TblWork` WHERE IFNULL(`Date1`, DATE(‘2012-11-20’)) = :cndDate;
NULLの場合の戻り値にDATE関数を使ってみるも変わらず。
(4) 条件の形式を変えてみた → ○
SELECT * FROM `TblWork` WHERE `Date1` = ‘2012-11-20’;
「/」を使った編集形式が悪いのは分かってるんだ、うん…。
(5) 列の方にDATE関数を使ってみた → ○
SELECT * FROM `TblWork` WHERE DATE(IFNULL(`Date1`, ‘2012-11-20’)) = :cndDate;
(6) 条件の方にDATE関数を使ってみた → ○
SELECT * FROM `TblWork` WHERE IFNULL(`Date1`, ‘2012-11-20’) = DATE(:cndDate);
うんまあ、素直に「yyyy-mm-dd」使えばいいんでしょうね。
でも、(3)と(5)の違いが分かんないんだわー。とか思ってたら、こういうことだそうです。
IFNULL(expr1,expr2)
expr1 が NULL でない場合、IFNULL() は expr1 を戻し、それ以外では expr2
を戻します。IFNULL() は、使用されている文脈によって、数値値もしくはスト
リング値を戻します。
IFNULL関数、文字列型で返すのですね…。(3)は文字列同士の比較になってるから「2012-11-20」(文字列)と「2012/11/20」(文字列)で一致せず、だったわけですね。んで、(5)は「2012-11-20」(日付)と「2012/11/20」(日付に変換)で一致したと。そういうことですかね。
うーん、分からん。地道に試すしかないのでしょうかね。ううう。
あ、多分プレースホルダとかpdoとかは関係ない感じ。