2008-11-16 106 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中有或没有空格)。