目前,我们对枚举字段中MySQL的排序顺序存在一个相互关联的问题。字段枚举条目已按我们想要的顺序排序。为了保存,我们在它周围添加了一个CONCAT,因此它将被转换为char并按字母顺序排序,正如MySQL-reference(MySQL Reference - Enum)
所建议的那样确保通过编码ORDER BY CAST(col AS CHAR)或ORDER BY CONCAT(col)对列进行词法排序而不是索引编号。
但这并没有产生预期的结果,所以我们开始进一步调查。似乎order by语句对enum和concat函数的组合不起作用。我写了下面的示例脚本,它应该表明我的观点:
CREATE TABLE test (
`col1` enum('a','b','c') COLLATE utf8_bin DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
INSERT INTO test
VALUES ('b'), ('c'), ('a');
SELECT * FROM test; -- b, c, a
SELECT * FROM test ORDER BY col1 ASC; -- a, b, c
SELECT * FROM test ORDER BY CAST(col1 AS CHAR) ASC; -- a, b, c
SELECT * FROM test ORDER BY CAST(col1 AS BINARY) ASC; -- a, b, c
SELECT * FROM test ORDER BY CONCAT(col1) ASC; -- b, c, a - This goes wrong
我目前怀疑整理/编码存在某种问题,但我不确定。我的数据库默认编码也是utf8。 MySQL版本是5.6.12但它似乎可以用MySQL 5.1重现。存储引擎是MyIsam,但它也与内存引擎一起发生。
任何帮助都将不胜感激。
更新:
因为看起来问题只出现在MySQL 5.6和列的整理中。使用第一个CREATE TABLE语句,查询可以正常工作。
CREATE TABLE test (
`col1` enum('a','b','c') COLLATE utf8_general_ci DEFAULT NULL
)
第二个他们没有。
CREATE TABLE test (
`col1` enum('a','b','c') COLLATE utf8_bin DEFAULT NULL
)
表和/或数据库的排序规则似乎不会影响查询。可以在此SQL Fiddle
中测试查询答案 0 :(得分:2)
很奇怪,它适用于这个小提琴。你有触发器吗?
http://sqlfiddle.com/#!2/0976a/2
但是,在5.6中出现了问题:
http://sqlfiddle.com/#!9/0976a/1
可能是Mysql错误。
此外,如果您以“正确”顺序输入枚举中的值,则可以正常工作:
http://sqlfiddle.com/#!9/a3784/1
在文档中:
ENUM值根据其索引号进行排序,这取决于 枚举成员在列中列出的顺序 规格。例如,'b'在'a'之前为ENUM排序('b','a')。
答案 1 :(得分:0)
根据document:
在Handling of Enumeration Literals
部分下,它声明:
如果将数字存储到ENUM列中,则该数字将被视为 索引到可能的值,并且存储的值是 具有该索引的枚举成员。 (但是,这不起作用 LOAD DATA,将所有输入视为字符串。)如果数值为 引用,如果没有匹配,它仍然被解释为索引 枚举值列表中的字符串。由于这些原因,事实并非如此 建议定义具有外观枚举值的ENUM列 喜欢数字,因为这很容易让人感到困惑。 例如,以下列的枚举成员的字符串值为“0”,“1”和“2”,但数字索引值为1,2和3:
numbers ENUM('0','1','2')
如果存储2,则将其解释为 索引值,并变为'1'(索引为2的值)。如果你存储 '2',它匹配枚举值,因此它存储为'2'。如果你 存储'3',它与任何枚举值都不匹配,因此它被处理 作为索引并变为'2'(索引为3的值)。
mysql> INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql> SELECT * FROM t;
+---------+
| numbers |
+---------+
| 1 |
| 2 |
| 2 |
+---------+
在你的情况下:
INSERT INTO test
VALUES ('2'), ('3'), ('1');
“2”的索引值为2,“3”为3,“1”为1。
因此输出为2,3,1