我有一个名为price
的列,我想输入一个价格并获得下一个最昂贵的商品,或者如果输入的价格超出表格中可用的范围,则显示最贵的商品。
例如,我的表格中有以下项目
id category price
1 Toys 12
2 Toys 14
3 Toys 18
4 Toys 40
5 Toys 38
6 Toys 67
因此,如果我输入20,我希望返回玩具编号5(价格38),因为这是下一个大数字。如果我输入超出表格范围的价格,例如100然后我想要退回最贵的物品,即6号玩具。
目前我的查询类似于
select *
from items
where category = ? and price > ?
order by price limit 1;
这将返回下一个最昂贵的玩具或任何其他类别的任何其他项目,但如果我输入100,那么我将如何显示最昂贵的项目?我可以在价格列上设置多个or
吗?
重要:我想在不使用合并的情况下实现此目的,或者如果可能的话,如果为null条件
答案 0 :(得分:1)
这是一种方法:
select i.*
from items i
where category = ?
order by (price > ?) desc,
(case when price > ? then price end) asc,
price desc
limit 1;
然而,更好的方法(在性能方面)可能是这样的:
(select i.*
from items i
where category = ? and price > ?
order by price asc
limit 1
) union all
(select i.*
from items i
where category = ?
order by price desc
limit 1
)
order by price
limit 1;
如果第一个子查询没有返回任何行,则第二个子查询将返回。排序两行的开销很小(每个子查询为limit 1
)。并且,这应该充分利用items(category, price)
上的两个子查询的索引。
答案 1 :(得分:1)
你可以试试这个
SELECT i.*
FROM items i
WHERE category = ?
AND ( price > ?
OR NOT EXISTS(SELECT 1
FROM items
WHERE category = ?
AND price > ?) )
order by (Case when price >? then price else 0-price end)
limit 1;