我得到下面的错误时,试图做一个选择通过一个存储过程在MySQL。

操作'='的排序规则(latin1_general_cs,IMPLICIT)和(latin1_general_ci,IMPLICIT)的非法混合

你知道哪里出了问题吗?

该表的排序规则为latin1_general_ci, where子句中的列的排序规则为latin1_general_cs。


当前回答

有时转换字符集可能是危险的,特别是在具有大量数据的数据库上。我认为最好的选择是使用“二进制”操作符:

e.g : WHERE binary table1.column1 = binary table2.column1

其他回答

这通常是由于比较两个排序规则不兼容的字符串或试图将不同排序规则的数据选择到一个组合列中而导致的。

子句COLLATE允许您指定查询中使用的排序规则。

例如,下面的WHERE子句总是会给出你发布的错误:

WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_cs

您的解决方案是为查询中的两个列指定共享排序规则。下面是一个使用COLLATE子句的例子:

SELECT * FROM table ORDER BY key COLLATE latin1_general_ci;

另一种选择是使用BINARY操作符:

二进制str是CAST(str AS BINARY)的简写。

你的解决方案可能是这样的:

SELECT * FROM table WHERE BINARY a = BINARY b;

or,

SELECT * FROM table ORDER BY BINARY a;

请记住,正如Jacob Stamm在评论中指出的那样,“转换列来进行比较将导致忽略该列上的任何索引”。

关于整理业务的更多细节,我强烈推荐eggyal对这个问题的出色回答。

解决方案,如果文字涉及。

我使用Pentaho数据集成,不需要指定sql语法。 使用非常简单的DB查找就会出现错误 "操作'='的排序规则(cp850_general_ci, coerble)和(latin1_swedish_ci, coerble)的非法混合"

生成的代码是 SELECT DATA_DATE AS latest DATA_DATE FROM hr_cc_normalised_data_date_v WHERE PSEUDO_KEY = ?"

长话短说,查找是一个视图,当我发布

mysql> show full columns from hr_cc_normalised_data_date_v;
+------------+------------+-------------------+------+-----+
| Field      | Type       | Collation         | Null | Key |
+------------+------------+-------------------+------+-----+
| PSEUDO_KEY | varchar(1) | cp850_general_ci  | NO   |     |
| DATA_DATE  | varchar(8) | latin1_general_cs | YES  |     |
+------------+------------+-------------------+------+-----+

这就解释了“cp850_general_ci”的来源。

视图是用'SELECT 'X',......'创建的 根据手册,这样的文字应该从服务器设置继承字符集和排序规则服务器设置被正确地定义为" latin1 "和" latin1_general_cs " 因为这显然没有发生,我强迫它在创建视图

CREATE OR REPLACE VIEW hr_cc_normalised_data_date_v AS
SELECT convert('X' using latin1) COLLATE latin1_general_cs        AS PSEUDO_KEY
    ,  DATA_DATE
FROM HR_COSTCENTRE_NORMALISED_mV
LIMIT 1;

现在它为两个列显示latin1_general_cs,错误已经消失。:)

有时转换字符集可能是危险的,特别是在具有大量数据的数据库上。我认为最好的选择是使用“二进制”操作符:

e.g : WHERE binary table1.column1 = binary table2.column1

把我的2c加入到未来谷歌员工的讨论中。

我正在调查一个类似的问题,在使用接收varchar参数的自定义函数时,我得到了以下错误:

Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and 
(utf8_general_ci,IMPLICIT) for operation '='

使用以下查询:

mysql> show variables like "collation_database";
    +--------------------+-----------------+
    | Variable_name      | Value           |
    +--------------------+-----------------+
    | collation_database | utf8_general_ci |
    +--------------------+-----------------+

我能够告诉DB使用utf8_general_ci,而表是使用utf8_unicode_ci定义的:

mysql> show table status;
    +--------------+-----------------+
    | Name         | Collation       |
    +--------------+-----------------+
    | my_view      | NULL            |
    | my_table     | utf8_unicode_ci |
    ...

注意,视图具有NULL排序规则。视图和函数似乎有排序规则定义,即使该查询为一个视图显示为空。使用的排序规则是创建视图/函数时定义的DB排序规则。

可悲的解决方案是既改变db排序规则,又重新创建视图/函数,迫使它们使用当前的排序规则。

更改db的排序规则: ALTER DATABASE mydb DEFAULT COLLATE utf8 更改表格排序规则: ALTER TABLE mydb CONVERT TO CHARACTER SET utf8 COLLATE

我希望这能帮助到一些人。

下面的方法对我很有效。

CONVERT( Table1.FromColumn USING utf8)    =  CONVERT(Table2.ToColumn USING utf8)