2008-11-16 30 views
8

Tôi có một điều tra: ENUM('alpha', 'beta', 'gamma', 'delta', 'omega')Tôi có thể so sánh các enums của MySQL không?

Nếu tôi sắp xếp bảng theo cột này, tôi sẽ đưa chúng theo thứ tự đúng được xác định ở trên.

Tuy nhiên, tôi không thể tìm cách chọn tập hợp con này, ví dụ: mọi thứ trước delta. Sử dụng WHERE status < 'delta' chỉ trả về alpha và beta chứ không trả về gamma. Có vẻ như MySQL sử dụng một so sánh chuỗi, không so sánh chỉ số enum.

Tôi có thể sử dụng số chỉ mục - nghĩa là WHERE status < 4 - nhưng hơi có mùi mã (số ma thuật) và có thể bị hỏng nếu tôi chèn giá trị mới vào liệt kê.

Trả lời

7

Bạn đang cố gắng sử dụng các phương pháp thao tác dữ liệu trên siêu dữ liệu và điều này nhất định là khó xử.

Đây là lý do chính đáng để thay thế ENUM bằng khóa ngoài thành bảng tra cứu. Sau đó, bạn có thể sử dụng các kỹ thuật thao tác dữ liệu thông thường.

2

Bạn có thể sử dụng FIELD(column, "string1", "string2", ...) để tìm các hàng có bất kỳ tập hợp con cụ thể nào có thể là ENUM giá trị.

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

Nếu bạn muốn sử dụng phiên bản phạm vi, bạn có thể sử dụng FIND_IN_SET("needle", "hay,stack") để trả lại chỉ số nhưng bạn sẽ phải trích xuất danh sách ENUM ra khỏi định nghĩa bảng đầu tiên với truy vấn khác.

3

chỉ gặp vấn đề tương tự. nếu bạn muốn sắp xếp một trường enum bạn phải bỏ nó vào một kiểu chuỗi đầu tiên (loại là trường enum của tôi trong ví dụ):

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

eazy!

+0

Điều này nghe giống với câu hỏi của tôi. Tôi muốn thứ tự được số, mà nó làm tốt. Vấn đề của tôi là với mệnh đề WHERE. Mặc dù có lẽ có một cách để chuyển đổi trường ENUM thành một giá trị số và sử dụng nó? Không thực sự quan trọng với tôi bây giờ, tôi hỏi điều này gần một năm trước và tôi thậm chí không nhớ những gì nó đã cho ... – DisgruntledGoat

0

Tạo một hàm:

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 

Sau đó, sử dụng nó trong một truy vấn như sau:

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

SELECT REPLACE(REPLACE(REPLACE(COLUMN_TYPE,''', ''',','),'enum(',''),')','') sẽ lấy số COLUMN_TYPE chẳng hạn như ENUM('alpha', 'beta', 'gamma', 'delta', 'omega') và biến nó thành danh sách được phân cách bằng dấu phẩy: 'alpha, beta, gamma, delta, omega'. Sau đó, FIND_IN_SET(_val, _lst) lấy chỉ mục.

Điều duy nhất bạn cần phải cẩn thận là cách bạn xác định ENUM (có hoặc không có dấu cách giữa các mục) và bên trong nhất REPLACE (có hoặc không có khoảng trống trong from_string).

Các vấn đề liên quan