MySQL-IN()中的ORDER BY值


107

我希望按照在IN()函数中输入的顺序对以下查询中返回的项目进行排序。

输入:

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

输出:

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

有任何想法吗?

Answers:


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

函数返回字符串的剩余列表中的第一个字符串的位置。

但是,在性能上要好得多,先有一个索引列代表您的排序顺序,然后再按此列进行排序。


9
@Vladimir-是的,它特定于MySQL。问题有mysql标签。
艾曼·胡里厄

很好,可以在数据库切换后替换Oracle的“解码”功能。
马丁·林恩

7
小心。任何未知的属性值(不在列表中)将优先于已知值,即FIELD(letter, 'A', 'C'),列表将首先返回以B字母开头的条目(假设一组具有A | B | C值的记录)。为了避免这种情况,请反转列表并使用DESC,即FIELD(letter, 'C', 'A') DESC
Gajus

如何在SQL Server中实现此目的。
user123456 '19

29

此处的另一个选项: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;

因此,在您的情况下(未经测试)

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';

根据您的操作,我发现它有些古怪,但是在玩了一点之后总能使它正常工作。


这可能比使用field()函数作为另一个建议的答案要好,因为使用field()会阻止索引的使用,但是它有机会使用此方法使用索引(尽管不确定使用索引的程度如何)
ʞɔıu


3

可能这可以帮助某人(SP中传递了p_CustomerId):

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;

说明:我想显示帐户列表。我在这里通过一个客户ID。现在,它将列出带有链接到该客户的帐户的帐户名称,并在顶部显示其后,然后按字母顺序排列其他帐户。



0

只是使用

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

避免像

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

将以无序结果行结尾:1和11交替

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.