最近在做數據庫的遷移的時候發現一個查詢SQL執行不了,發生異常:
mysql Illegal mix of collations for operation 'UNION’
頭挺大,一番搜索發現是表字段的字符集的問題。
但是聯想到我們出錯的這個SQL :
select count(1) from (
select ns.name,ns.sex,pa.mobile,pa.dynamicList,pa.createdList,pa.created dynamicTime,s.regist_time,s.source,adv.name adviserName from (
select house_id,mobile,GROUP_CONCAT(dynamic order by created) dynamicList,GROUP_CONCAT(created order by created) createdList,max(created) created from (
select house_id,mobile,created,dynamic from customer_dynamic where dynamic in (1) and house_id=1
)aa group by aa.house_id,aa.mobile) pa left join
(select * from (select mobile,name,sex from t_visit_record where house_id=1 and name is not null
union
select mobile,name,sex from t_dm_customer_state where house_id=1 and name is not null
union
select a.mobile,a.nickname,a.sex from brand_app_customer a left join brand_house_rlat b on a.brand_id=b.brand_id where b.house_id=1 and a.nickname is not null
) n group by n.mobile) ns on pa.mobile=ns.mobile
left join (select * from (
select * from (
select house_id,mobile,source,regist_time from customer_source where house_id=1
union all
select house_id,mobile,source,register_time from brand_app_customer_source where house_id=1
union all
select house_id,mobile,visit_type,visit_time from t_visit_record where house_id=1
) a order by a.regist_time is null
)b GROUP BY b.house_id,b.mobile
) s on s.mobile=pa.mobile
left join (select * from (select house_id,mobile,adviser_id from customer_follow where house_id=1 and status=1 order by id desc) cf group by cf.house_id,cf.mobile) cfa on pa.mobile=cfa.mobile
left join role_adviser adv on cfa.adviser_id=adv.id and adv.status=1
where pa.house_id=1
and s.regist_time > '2020-06-01 00:00:00' and s.regist_time < '2020-06-30 00:00:00'
and (ns.name like '%隨便輸入%' collate utf8mb4_general_ci or pa.mobile like '%隨便輸入%' or adv.name like '%隨便輸入%' or adv.mobile like '%隨便輸入%')
) a;
這讓我去檢查每個表的字段,這酸爽簡直讓人不敢相信。
經過一陣痛苦的思考後,聯想到Mysql其實針對每個表也是有一個專門的庫存儲的information_schema
,這個庫裏面的其中一張表就包含了所有字段名COLUMNS
。
然後通過SQL查詢就能定位到和當前庫字符集不匹配的所有字段:
select * from information_schema.columns where table_schema = 'marketing_db' and data_type = 'varchar' and collation_name != 'utf8mb4_general_ci';
一搜索果然發現了一些不匹配的字符集。
瞬間改完之後,SQL就能夠正確執行了。
給後續採坑的有緣人一個提醒吧。
還是有事沒事多積累一些知識,看起來不重要的知識,可能在關鍵時刻能保命。