8

我有一个搜索查询,它根据输入参数产生一个结果集,并且可以根据不同的参数对结果进行排序(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 的记录保持在顶部?

4

3 回答 3

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

p.id=141如果条件为真,则返回,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,而且性能可能更好。

于 2012-08-06T07:14:48.393 回答
3

使用联合始终将您的包放在顶部:

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
于 2012-08-06T06:59:48.683 回答
1

试试这个:

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

而不是 (select MAX(p.mPrice)+1 from package ) 你可以给出一个常量值,它总是一个最大值,像这样

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

这会更有效

于 2012-08-06T07:03:58.470 回答