我能比较MySQL枚举吗?

11

我有一个枚举:ENUM('alpha', 'beta', 'gamma', 'delta', 'omega')

如果我按照这个列排序,我可以得到与上面定义的正确顺序相同的结果。

然而,我找不到一种方法来选择其中的子集,例如在delta之前的所有内容。使用WHERE status < 'delta'只返回alpha和beta,而不是gamma。似乎MySQL使用字符串比较而非枚举索引比较。

我可以使用索引号码 - 也就是WHERE status < 4,但这有点像代码异味(神奇数字),并且可能会在将来插入新值时出错。

5个回答

9

7
你试图在元数据上使用数据操纵方法,这是很麻烦的。因此,将ENUM替换为外键到查找表是一个好的选择。这样你就可以使用常规的数据操作技术。

3

我刚刚遇到了相同的问题。如果您想对枚举字段进行排序,首先必须将其转换为字符串类型(在此示例中,category是我的枚举字段):

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

简单易懂!


2
这听起来和我的问题相反。 我想要的排序是数字形式的,这个可以做得很好。我的问题在于WHERE子句。不过也许有一种方法可以将ENUM字段转换为数值,然后使用它?现在对我来说真的没什么关系了,我提出这个问题将近一年了,我甚至都不记得当时是为了什么了... - DisgruntledGoat

2
您可以使用FIELD(column, "string1", "string2", ...)函数来查找具有任何特定子集的ENUM值的行。
SELECT * FROM `table` WHERE FIELD(`enum_column`, "alpha", "delta", "et cetera");

如果您想使用范围版本,可以使用FIND_IN_SET("needle", "hay,stack")来返回索引,但是您需要先使用另一个查询从表定义中提取ENUM列表。请保留HTML标签。

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中是否带有空格)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接