我有一个搜索查询,根据输入参数生成结果集,结果可以根据不同的参数进行排序(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的记录以保持在顶部?
答案 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
哪个会更有效率