2013-09-25 39 views
2

目前我們在枚舉字段中有一個關於MySQL排序順序的明顯問題。字段枚舉項已按照我們想要的順序排序。只是要節省,我們增加了一個CONCAT圍繞它,所以它會被轉換爲char,並下令按字母順序排列,就像建議由MySQL引用(MySQL Reference - EnumMySQL Order By不適用於Concat(enum)

確保列詞彙整理而不是通過編碼ORDER BY CAST(col AS CHAR)或ORDER BY CONCAT(col)通過索引編號。

但是這並沒有產生預期的結果,所以我們開始進一步調查。看來order by語句不能用於枚舉和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

回答

2

奇怪的是,它在這個小提琴中起作用。你有觸發器還是什麼?

http://sqlfiddle.com/#!2/0976a/2

,但在5.6進入瘋狂:

http://sqlfiddle.com/#!9/0976a/1

Mysql的錯誤,很可能。

更多,如果你輸入 「正確」 的順序在枚舉值它的工作原理:

http://sqlfiddle.com/#!9/a3784/1

在DOC:

ENUM值進行排序基於其指數數字,這取決於 列舉成員在列 規範列出的順序。例如,'b'在ENUM('b','a')的'a'之前排序。

+0

正如你所說,目前我傾向於認爲這是一個MySQL錯誤。如果在接下來的幾天內我不會再提供其他解釋,我會盡力將其報告爲一個錯誤。 – Aceonline

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  | 
+---------+ 

在你的情況: '2'

INSERT INTO test 
VALUES ('2'), ('3'), ('1'); 

索引值爲2, '3' 是3和 '1' 是1。 所以輸出2,3,1

+0

好的,爲了讓我的觀點更清晰,我調整了樣本值。如果使用'a','b'和'c'作爲枚舉值,則會出現同樣的問題。我知道枚舉的值是根據定義中的順序排序的。這就是爲什麼我首先添加了CONCAT的原因。 – Aceonline

+1

你可以檢查你的服務器和數據庫的字符集。因爲它適合我。這裏是[SqlFiddle](http://sqlfiddle.com/#!9/622cf/1) – heretolearn

+0

我添加了對問題描述的更新。 – Aceonline