2008-11-16 157 views
8

我有一個枚舉:ENUM('alpha', 'beta', 'gamma', 'delta', 'omega')我可以比較MySQL枚舉嗎?

如果我按此列排序我的表,我按照上面定義的正確順序獲取它們。

但是,我找不到一種方法來選擇這些的一個子集,例如三角洲前的一切。使用WHERE status < 'delta'只返回alpha和beta,而不是gamma。看來MySQL使用字符串比較,而不是枚舉索引比較。

我可以使用索引號 - 即WHERE status < 4 - 但它有點代碼味道(幻數),並且如果我向枚舉中插入新值,可能會中斷。

回答

7

您試圖在元數據上使用數據操作方法,這勢必會很尷尬。

這是將ENUM替換爲查找表的外鍵的好理由。然後你可以使用傳統的數據處理技術。

3

剛剛遇到同樣的問題。如果要排序一個枚舉領域,你必須將它轉換爲字符串類型的第一個(類是我的枚舉場中的例子):

SELECT 
CONVERT(category USING utf8) as str_category 
FROM 
example 
GROUP BY 
str_category 
ORDER BY 
str_category 

EAZY!

+0

這聽起來像我的問題相反。我想要的訂單是數字,它沒有問題。我的問題是與WHERE子句。雖然也許有一種方法可以將ENUM字段轉換爲數值並使用它?現在對我來說無所謂,我在近一年前問過這個問題,我什至不記得它是什麼... – DisgruntledGoat 2009-10-13 15:35:41

0

創建一個函數:

CREATE fEnumIndex(_table VARCHAR(50), _col VARCHAR(50), _val VARCHAR(50)) 
RETURNS INT DETERMINISTIC 
BEGIN 
    DECLARE _lst VARCHAR(8192); 
    DECLARE _ndx INT; 

    SELECT REPLACE(REPLACE(REPLACE(COLUMN_TYPE,''', ''',','),'enum(',''),')','') 
    FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND 
    TABLE_NAME=_table AND COLUMN_NAME=_col INTO _lst; 
    SET _ndx = FIND_IN_SET(_val, _lst); 
    RETURN _ndx; 
END 

然後在查詢中使用它,如下所示:

SELECT * FROM MyTable WHERE Status < fEnumIndex('MyTable','Status','delta') ; 

SELECT REPLACE(REPLACE(REPLACE(COLUMN_TYPE,''', ''',','),'enum(',''),')','')將採用COLUMN_TYPE,如ENUM('alpha', 'beta', 'gamma', 'delta', 'omega'),並將其變成逗號分隔列表:'alpha, beta, gamma, delta, omega'。然後FIND_IN_SET(_val, _lst)獲取索引。

唯一需要注意的是如何定義ENUM(在項目之間有或沒有空格)和最內部的REPLACE(在from_string中有或沒有空格)。