對比 DATE_FORMAT() 與 TIMEDIFF() 時觸發 ERROR 1267: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,NUMERIC) for operation '>'。本文深度解析 DATE_FORMAT 返回值攜帶連接層字符集屬性、TIMEDIFF 返回二進制字符串的機制差異,給出 CONVERT 顯式轉換與會話級字符集統一兩種解決路徑。
SELECT DATE_FORMAT('2013-11-19','%Y-%m-%d') > TIMEDIFF('2013-11-19', '2013-11-20');
-- ERROR 1267 (HY000): Illegal mix of collations ... for operation '>'
DATE_FORMAT()returns a string with a character set and collation given bycharacter_set_connectionandcollation_connectionso that it can return month and weekday names containing non-ASCII characters.
TIMEDIFF() 無此說明,返回 binary 字符集。
SET NAMES utf8;
SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
-- 結果:utf8 | binary
SET NAMES gb2312;
SELECT CHARSET(DATE_FORMAT('2013-11-19','%Y-%m-%d')), CHARSET(TIMEDIFF('2013-11-19', '2013-11-20'));
-- 結果:gb2312 | binary
結論:DATE_FORMAT 結果字符集隨 character_set_connection 變化;TIMEDIFF 固定 binary。比較操作時,MySQL 嘗試隱式轉換失敗,拋出 collation 混合錯誤。
SELECT DATE_FORMAT('2013-11-19','%Y-%m-%d') >
CONVERT(TIMEDIFF('2013-11-19', '2013-11-20') USING utf8);
-- 成功返回 1
也可用 CAST(... AS CHAR CHARACTER SET utf8)。
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 或在 my.cnf [client]/[mysql] 設置 default-character-set
-- 則 DATE_FORMAT 返回 utf8mb4,TIMEDIFF 仍為 binary,但比較時隱式轉換規則不同,實測 8.0+ 可通過
⚠️ 5.7 及以下版本即使統一會話字符集,binary 與具體 collation 比較仍可能報錯,**方案一最通用穩健**。
| 符號 | 含義 | 示例 |
|---|---|---|
%S, %s | 秒 (00-59) | 05 |
%i | 分 (00-59) | 30 |
%H | 小時 24制 (00-23) | 14 |
%h, %I | 小時 12制 (01-12) | 02 |
%k | 小時 24制 (0-23) | 14 |
%l | 小時 12制 (1-12) | 2 |
%T | 時間 24制 (HH:MM:SS) | 14:30:05 |
%r | 時間 12制 (HH:MM:SS AM/PM) | 02:30:05 PM |
%p | AM/PM | PM |
%W | 星期全名 | Sunday |
%a | 星期縮寫 | Sun |
%d | 月內天數 (01-31) | 19 |
%e | 月內天數 (1-31) | 19 |
%D | 帶英文後綴 | 19th |
%w | 星期索引 (0=Sunday) | 0 |
%j | 年內天數 (001-366) | 323 |
%U | 周數 (00-53, Sunday第一天) | 46 |
%u | 周數 (00-53, Monday第一天) | 46 |
%M | 月份全名 | November |
%b | 月份縮寫 | Nov |
%m | 月份 (01-12) | 11 |
%c | 月份 (1-12) | 11 |
%Y | 年份 4位 | 2013 |
%y | 年份 2位 | 13 |
%% | 字面 % | % |
DATE_FORMAT 返回值攜帶連接字符集屬性,TIMEDIFF 等時間函數返回 binary,混合比較觸發 collation 衝突。**顯式 CONVERT(... USING charset) 是最精準、版本通用的解法**。開發規範建議:SQL 中涉及字符串與時間/數值比較時,統一顯式 CAST/CONVERT,消除隱式轉換風險。