如何确保记录始终位于mysql中给定结果集的顶部?

时间:2012-08-06 06:52:19

标签: mysql sql sql-order-by

我有一个搜索查询,根据输入参数生成结果集,结果可以根据不同的参数进行排序(ASC / DESC):价格,持续时间等(分页到位,限制为10条记录)

我现在有一个要求,其中,如果我传入id,我希望相应的记录在给定结果集的顶部粘贴。

假设我们有这样的包表:

Package
 - id
 - name
 - mPrice
 - vPrice
 - duration

// Searching pkg based on Price (in DESC order) where name = Thailand
sqlQuery = 
"SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') 
ORDER BY (p.mPrice + p.vPrice) DESC 
LIMIT 10"

假设完整的结果集是20条记录,其中id为1到20.我现在需要返回id为14的记录,始终位于顶部。我提出了以下查询,但这不起作用:

sqlQuery = 
"SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') or p.id = 14
ORDER BY CASE 
WHEN p.id=14 then 0 
else (p.mPrice + p.vPrice) 
end DESC 
LIMIT 10"

我猜测为什么这不起作用:在order by子句之后,结果集按降序排序,然后在10条记录中被截断。 id = 14的记录可能不是此截断集的一部分。这是对的吗?

如何获得id = 14的记录以保持在顶部?

3 个答案:

答案 0 :(得分:16)

ORDER BY (p.id=14) DESC, (p.mPrice=p.vPrice) DESC

p.id=14如果条件为真,则返回1,否则返回0,因此排序降序会将所需的行带到顶部。

从比较中返回一个数字是一个MySQL功能,您可以编写标准SQL:

ORDER BY CASE WHEN (p.id=14) THEN 0 ELSE 1 END,
         CASE WHEN (p.mPrice=p.vPrice) THEN 0 ELSE 1 END

我觉得这比UNION更容易阅读,而且效果可能更好。

答案 1 :(得分:2)

使用联合始终将您的包裹放在最上面:

SELECT id, name, mPrice, vPrice FROM package WHERE id = 14
UNION
SELECT p.id, p.name, p.mPrice, p.vPrice FROM package p 
WHERE p.name = LOWER('Thailand') or p.id = 14
ORDER BY (p.mPrice = p.vPrice) DESC
LIMIT 9

答案 2 :(得分:0)

试试这个:

order by 
 case when p.id=14 then then (select MAX(mPrice)+1 from package ) else
(p.mPrice = p.vPrice)  end desc
LIMIT 10

而不是(从包中选择MAX(p.mPrice)+1),您可以给出一个常量值,该值始终为最大值,类似这样

 order by 
 case when p.id=14 then then 1000000 else
(p.mPrice = p.vPrice)  end desc
LIMIT 10

哪个会更有效率