MySQL - ĐẶT HÀNG BẰNG giá trị trong IN ()


107

Tôi hy vọng sắp xếp các mục được trả về trong truy vấn sau theo thứ tự chúng được nhập vào hàm IN () .

ĐẦU VÀO:

SELECT id, name FROM mytable WHERE name IN ('B', 'A', 'D', 'E', 'C');

ĐẦU RA:

|   id   |   name  |
^--------^---------^
|   5    |   B     |
|   6    |   B     |
|   1    |   D     |
|   15   |   E     |
|   17   |   E     |
|   9    |   C     |
|   18   |   C     |

Bất kỳ ý tưởng?

Câu trả lời:


231
SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY FIELD(name, 'B', 'A', 'D', 'E', 'C')

Hàm FIELD trả về vị trí của chuỗi đầu tiên trong danh sách các chuỗi còn lại.

Tuy nhiên, hiệu suất tốt hơn nhiều nếu có một cột được lập chỉ mục đại diện cho thứ tự sắp xếp của bạn, rồi sắp xếp theo cột này.


9
@Vladimir - vâng, nó dành riêng cho MySQL. Câu hỏi có thẻ mysql.
Ayman Hourieh

Tuyệt vời, thay thế cho chức năng "giải mã" của Oracle sau khi chuyển đổi DB.
Martin Lyne

7
Cẩn thận. Mọi giá trị thuộc tính không xác định (không có trong danh sách) sẽ được ưu tiên hơn các giá trị đã biết, tức là FIELD(letter, 'A', 'C'), danh sách sẽ trả về các mục nhập có chữ B trước (giả sử một tập hợp các bản ghi có A | B | Cgiá trị). Để tránh điều đó, hãy đảo ngược danh sách và sử dụng DESC, tức là FIELD(letter, 'C', 'A') DESC.
Gajus

Làm cách nào để đạt được điều này trong máy chủ SQL.
user123456

29

Một tùy chọn khác từ đây: http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html

select * 
from tablename 
order by priority='High' DESC, priority='Medium' DESC, priority='Low" DESC;

Vì vậy, trong trường hợp của bạn (chưa được kiểm tra) sẽ là

SELECT id, name
FROM mytable
WHERE name IN ('B', 'A', 'D', 'E', 'C')
ORDER BY name = 'B', name = 'A', name = 'D', name =  'E', name = 'C';

Tùy thuộc vào những gì bạn đang làm, tôi thấy nó hơi kỳ quặc nhưng luôn có tác dụng sau khi chơi với nó một chút.


Điều này có thể tốt hơn so với việc sử dụng hàm field () như một câu trả lời khác được đề xuất bởi vì sử dụng trường () sẽ loại trừ việc sử dụng chỉ mục, nhưng nó có cơ hội sử dụng chỉ mục bằng phương pháp này (mặc dù không chắc nó có thể sử dụng chỉ mục tốt như thế nào)
ʞɔıu

4

Hãy thử một cái gì đó như

... ORDER BY (CASE NAME WHEN 'B' THEN 0 WHEN 'A' THEN 1 WHEN ...

3

Có thể điều này có thể giúp ai đó (p_CustomerId được chuyển trong SP):

SELECT CompanyAccountId, CompanyName
FROM account
LEFT JOIN customer where CompanyAccountId = customer.AccountId
GROUP BY CompanyAccountId
ORDER BY CASE WHEN CompanyAccountId IN (SELECT AccountId 
                                          FROM customer
                                          WHERE customerid= p_CustomerId) 
                 THEN 0
                 ELSE 1
          END, CompanyName;

Mô tả: Tôi muốn hiển thị danh sách tài khoản. Ở đây tôi đang chuyển một id khách hàng trong sp. Bây giờ, nó sẽ liệt kê các tên tài khoản với các tài khoản được liên kết với khách hàng đó được hiển thị ở trên cùng, tiếp theo là các tài khoản khác theo thứ tự bảng chữ cái.


2

Bạn cần một cột khác (số) trong bảng của mình, trong đó bạn chỉ định thứ tự sắp xếp. Mệnh đề IN không hoạt động theo cách này.

B - 1
A - 2
D - 3
E - 4
C - 5

2
Thứ tự mong muốn có thể là mỗi truy vấn.
Vladimir Dyuzhev

0

chỉ dùng

order by INSTR( ',B,C,D,A,' ,  concat(',' , `field`, ',' ) )

tránh tình huống như

 INSTR('1,2,3,11' ,`field`) 

sẽ kết thúc với hàng kết quả không có thứ tự: 1 và 11 thay thế

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.