執行 SELECT DATE_FORMAT(...) > TIMEDIFF(...) 報錯 Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,NUMERIC)。根因:DATE_FORMAT() 回傳帶有連線字元集/校對集屬性的字串,而 TIMEDIFF() 回傳二進位字串(無字元集),兩者直接比較觸發校對集衝突。
mysql> SET NAMES utf8;
mysql> SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
+---------------------------------------------------+--------------------------------------------------+
| CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')) | CHARSET(TIMEDIFF('2013-11-19', '2013-11-20')) |
+---------------------------------------------------+--------------------------------------------------+
| utf8 | binary |
+---------------------------------------------------+--------------------------------------------------+
mysql> SET NAMES gb2312;
mysql> SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
+---------------------------------------------------+--------------------------------------------------+
| CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')) | CHARSET(TIMEDIFF('2013-11-19', '2013-11-20')) |
+---------------------------------------------------+--------------------------------------------------+
| gb2312 | binary |
+---------------------------------------------------+--------------------------------------------------+
DATE_FORMAT() 的字元集隨 character_set_connection/collation_connection 變化;TIMEDIFF() 永遠回傳 binary。
SELECT DATE_FORMAT('2013-11-19','%Y-%m-%d')
> CONVERT(TIMEDIFF('2013-11-19', '2013-11-20') USING utf8);
或統一轉為 binary:
SELECT CONVERT(DATE_FORMAT('2013-11-19','%Y-%m-%d') USING binary)
> TIMEDIFF('2013-11-19', '2013-11-20');
CONVERT(... USING charset) 或 CAST(... AS BINARY) 顯式統一。SET NAMES utf8mb4,減少隱含轉換驚喜。DATE_FORMAT 格式字串用 %Y-%m-%d(非 Y-m-d),原文範例格式錯誤已修正。