我有下表
DROP TABLE IF EXISTS `test`.`foo`;
CREATE TABLE `test`.`foo` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)
然后我尝试根据主键获取记录
SELECT * FROM foo f where f.id IN (2, 3, 1);
Run Code Online (Sandbox Code Playgroud)
然后我得到以下结果
+----+--------+
| id | name |
+----+--------+
| 1 | first |
| 2 | second |
| 3 | third |
+----+--------+
3 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
可以看出,结果按id排序.我想要实现的是按照我在查询中提供的顺序获取结果.鉴于此示例,它应该返回
+----+--------+
| id | name |
+----+--------+
| 2 | second |
| 3 | third |
| 1 | first |
+----+--------+
3 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
Ty *_*y W 86
正如另一个答案所提到的:您发布的查询没有关于您希望结果的顺序,只是您希望得到的结果.
要订购结果,我会使用ORDER BY FIELD():
SELECT * FROM foo f where f.id IN (2, 3, 1)
ORDER BY FIELD(f.id, 2, 3, 1);
Run Code Online (Sandbox Code Playgroud)
FIELD的参数列表可以是可变长度.
Bil*_*win 23
IN()谓词中的值被视为一个集合,SQL查询返回的结果无法自动推断该集合的顺序.
通常,除非您使用ORDER BY子句指定订单,否则任何SQL查询的顺序都是任意的.
您可以使用MySQL函数FIND_IN_SET()执行您想要的操作:
SELECT * FROM foo f where f.id IN (2, 3, 1)
ORDER BY FIND_IN_SET(f.id, '2,3,1');
Run Code Online (Sandbox Code Playgroud)
请注意,list参数to FIND_IN_SET()不是可变长度列表,如参数IN().它必须是字符串文字或SET.
重新关于性能的问题:我很好奇了,所以我都尝试FIND_IN_SET()和FIELD()方法,对我的StackOverflow的数据副本:
在VoteTypeId上没有索引:
SELECT * FROM Votes ORDER BY FIND_IN_SET(VoteTypeId, '13,1,12,2,11,3,10,4,9,5,8,6,7');
3618992 rows in set (31.26 sec)
3618992 rows in set (29.67 sec)
3618992 rows in set (28.52 sec)
SELECT * FROM Votes ORDER BY FIELD(VoteTypeId, 13,1,12,2,11,3,10,4,9,5,8,6,7);
3618992 rows in set (37.30 sec)
3618992 rows in set (49.65 sec)
3618992 rows in set (41.69 sec)
Run Code Online (Sandbox Code Playgroud)
使用VoteTypeId的索引:
SELECT * FROM Votes ORDER BY FIND_IN_SET(VoteTypeId, '13,1,12,2,11,3,10,4,9,5,8,6,7');
3618992 rows in set (14.71 sec)
3618992 rows in set (14.81 sec)
3618992 rows in set (25.80 sec)
SELECT * FROM Votes ORDER BY FIELD(VoteTypeId, 13,1,12,2,11,3,10,4,9,5,8,6,7);
3618992 rows in set (19.03 sec)
3618992 rows in set (14.59 sec)
3618992 rows in set (14.43 sec)
Run Code Online (Sandbox Code Playgroud)
结论:在有限的测试中,两种方法都没有很大的优势.
| 归档时间: |
|
| 查看次数: |
12764 次 |
| 最近记录: |