Могу ли я сравнить перечисления MySQL?

У меня есть перечисление: ENUM( 'alpha', 'beta', 'gamma', 'delta', 'omega' )

Если я отсортирую свою таблицу по этому столбцу, я получу их в правильном порядке, определенном выше.

Однако я не могу найти способ выбрать их подмножество, например все до дельты. Использование WHERE status < 'delta' возвращает только альфа и бета, но не гамму. Кажется, MySQL использует сравнение строк, а не сравнение индексов перечисления.

Я мог бы использовать номера индексов, то есть WHERE status < 4, но это немного запах кода (магические числа) и может сломаться, если я вставлю новые значения в перечисление.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
10
0
11 680
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете использовать 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

легко!

Это звучит как противоположность моему вопросу. Я хотел, чтобы порядок был числовым, и это нормально. Моя проблема была в предложении WHERE. Хотя, возможно, есть способ преобразовать поле ENUM в числовое значение и использовать его? Для меня это не имеет особого значения, я спросил об этом почти год назад и даже не помню, для чего это было ...

DisgruntledGoat 13.10.2009 19:35

Вы можете использовать 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 или без него).

Другие вопросы по теме