2015-10-20 47 views
0

我有一个名为price的列,我想输入一个价格并获得下一个最昂贵的物品,或者如果输入的价格超出了表中可用的范围,最昂贵的物品。如何在同一列上有多个OR条件

例如我有以下的项目在我的表

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吗?

重要:我想做到这一点,而无需使用合并或者空的条件,如果可能的

回答

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)这两个子查询的大量索引。

+0

@GrodonLinoff太感谢你了,第一个不知何故似乎并没有为我工作..让我尝试第二个。 –

+0

@ john.p.doe。 。 。请注意,通配符的数量已更改。 –

+0

将查询更改为此可为我提供所需的结果。如果我做错了任何事,请纠正我。 (价格>?)desc,(当价格>?则价格结束时)asc,price desc limit 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; 
+1

我编辑了以前的答案,它为我工作..但你的作品也很好。 Upvoted。非常感谢你的努力。 –