У меня есть перечисление: ENUM( 'alpha', 'beta', 'gamma', 'delta', 'omega' )
Если я отсортирую свою таблицу по этому столбцу, я получу их в правильном порядке, определенном выше.
Однако я не могу найти способ выбрать их подмножество, например все до дельты. Использование WHERE status < 'delta' возвращает только альфа и бета, но не гамму. Кажется, MySQL использует сравнение строк, а не сравнение индексов перечисления.
Я мог бы использовать номера индексов, то есть WHERE status < 4, но это немного запах кода (магические числа) и может сломаться, если я вставлю новые значения в перечисление.


Вы можете использовать FIELD(column, "string1", "string2", ...) для поиска строк с любым конкретным подмножеством возможных значений ENUM.
SELECT * FROM `table` WHERE FIELD(`enum_column`, "alpha", "delta", "et cetera");
Если вы хотите использовать версию диапазона, вы можете использовать FIND_IN_SET("needle", "hay,stack") для возврата индекса, но вам придется сначала извлечь список ENUM из определения таблицы с помощью другого запроса.
Вы пытаетесь использовать методы манипулирования данными для метаданных, и это обязательно будет неудобно.
Это хорошая причина заменить ENUM внешним ключом для таблицы поиска. Затем вы можете использовать обычные методы обработки данных.
просто столкнулся с той же проблемой. если вы хотите отсортировать поле перечисления, вам нужно сначала привести его к строковому типу (категория - это мое поле перечисления в примере):
SELECT
CONVERT(category USING utf8) as str_category
FROM
example
GROUP BY
str_category
ORDER BY
str_category
легко!
Вы можете использовать status+0 для возврата индекса ENUM, начиная с 1.
Обратитесь к http://serghei.net/docs/database/mysql/doc/E/N/ENUM.html
Создайте функцию:
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 или без него).
Это звучит как противоположность моему вопросу. Я хотел, чтобы порядок был числовым, и это нормально. Моя проблема была в предложении WHERE. Хотя, возможно, есть способ преобразовать поле ENUM в числовое значение и использовать его? Для меня это не имеет особого значения, я спросил об этом почти год назад и даже не помню, для чего это было ...