我想检索有序的查询结果,但我需要在列表前面放置一些特定的行。像Stack Overflow这样的东西,在答案列表中,正确答案总是第一个。
假设我需要将ID为1,2,3的行作为头部,其余的按日期字段排序,是否可以执行以下操作:
SELECT * FROM foo ORDER BY id IN (1,2,3), created_date
如果不是更有效率?会有很多行!
SELECT *, 0 AS head FROM foo WHERE id IN (1,2,3)
UNION
SELECT *, 1 AS head FROM foo WHERE id NOT IN (1,2,3)
ORDER BY head, created_date
或
SELECT *, IF(id IN (1,2,3), 0, 1) AS head
ORDER BY head, created_date
(我现在使用MySQL,但我对任何其他SQL解决方案感兴趣。)
答案 0 :(得分:3)
UNION表示UNION DISTINCT,这是相对较慢的,因为它会检查重复,即使没有任何重复。你想要UNION ALL:
SELECT *, 0 AS head FROM foo WHERE id IN (1,2,3)
UNION ALL
SELECT *, 1 AS head FROM foo WHERE id NOT IN (1,2,3)
ORDER BY head, created_date
我认为在这次改变之后,三个查询之间的性能差别不大。最好的方法是测量它。
答案 1 :(得分:2)
你的第一个例子几乎就在我身边。
SELECT * FROM foo ORDER BY id IN (1,2,3) DESC, created_date ASC
添加了DESC
,因为如果为id IN (1,2,3)
,则返回1
,如果为0
则返回1 > 0
。 ASC
,因此按降序排序会获得所需的结果。
添加field IN (list)
因为我喜欢明确。
根据您之后的示例,我认为您缺少的是,虽然它包含空格,但0
是一个返回1
或IF(id IN (1,2,3), 0, 1)
的运算符。 UNION
本质上是多余的。
因此,您不需要手动使用{{1}} 或排序,因为MySQL比您实现的更简单:)