2008-11-16 9 views
8

Ich habe eine Aufzählung: ENUM('alpha', 'beta', 'gamma', 'delta', 'omega')Kann ich MySQL-Enums vergleichen?

Wenn ich meine Tabelle nach dieser Spalte sortiere, bekomme ich sie in der richtigen Reihenfolge wie oben definiert.

Jedoch kann ich keinen Weg finden, eine Teilmenge von diesen auszuwählen, z.B. alles vor dem Delta. Mit WHERE status < 'delta' gibt nur Alpha und Beta, nicht Gamma zurück. Es sieht so aus, als ob MySQL einen String-Vergleich verwendet, nicht einen Enum-Index-Vergleich.

Ich könnte die Indexnummern verwenden - d. H. WHERE status < 4 - aber es ist ein bisschen ein Code-Geruch (magische Zahlen) und kann brechen, wenn ich neue Werte in die Aufzählung einfügen.

Antwort

7

Sie versuchen, Datenbearbeitungsmethoden für Metadaten zu verwenden, und das ist sicher umständlich.

Dies ist ein guter Grund, die ENUM durch einen Fremdschlüssel zu einer Nachschlagetabelle zu ersetzen. Dann können Sie herkömmliche Datenmanipulationstechniken verwenden.

2

Sie können FIELD(column, "string1", "string2", ...) verwenden, um Zeilen mit einer bestimmten Teilmenge von möglichen ENUM Werten zu finden.

SELECT * FROM `table` WHERE FIELD(`enum_column`, "alpha", "delta", "et cetera"); 

Wenn Sie den Bereich Version verwenden möchten, können Sie FIND_IN_SET("needle", "hay,stack") verwenden Sie den Index zurück, aber Sie werden die ENUM-Liste aus der Tabellendefinition extrahieren müssen zuerst mit einer anderen Abfrage.

3

kam gerade das gleiche Problem. wenn Sie eine Enum Feld sortieren möchten Sie es in einen String-Typ zu werfen haben erste (Kategorie ist mein Enum Feld im Beispiel):

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

Eazy!

+0

Das klingt wie das Gegenteil meiner Frage. Ich wollte, dass die Reihenfolge numerisch ist, was gut ist. Mein Problem war mit der WHERE-Klausel. Obwohl es vielleicht eine Möglichkeit gibt, das ENUM-Feld in einen numerischen Wert umzuwandeln und zu verwenden? Ist mir jetzt wirklich egal, ich fragte das vor fast einem Jahr und ich erinnere mich nicht einmal daran, wofür es war ... – DisgruntledGoat

0

eine Funktion erstellen:

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 

es dann in einer Abfrage verwenden, wie folgt:

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

Die SELECT REPLACE(REPLACE(REPLACE(COLUMN_TYPE,''', ''',','),'enum(',''),')','') wird die COLUMN_TYPE wie ENUM('alpha', 'beta', 'gamma', 'delta', 'omega') nehmen und es in eine durch Kommas getrennte Liste umwandeln: 'alpha, beta, gamma, delta, omega'. Dann erhält der FIND_IN_SET(_val, _lst) den Index.

Die einzige Sache, mit der Sie vorsichtig sein müssen, ist, wie Sie die ENUMs (mit oder ohne Leerzeichen zwischen den Elementen) und die innersten REPLACE (mit oder ohne Leerzeichen in der from_string) definieren.

Verwandte Themen