这是一个难以制定的问题(任何编辑都受到赞赏)但是这里有。假设您有两个表:FRUIT
和BASKET
。水果(代表实际物品,而不是水果品种)按篮子分组。以下是FRUIT
的一个示例:
FRUIT_ID WEIGHT_IN_GRAMS BASKET_ID FRUIT_TYPE
-------- --------------- --------- ----------
1 100 1 Apple
2 200 1 Orange
3 150 1 Lemon
4 100 2 Apple
5 300 2 Plum
我想要的是{{1>}每个篮子中最重的水果。换句话说:
FRUIT_ID
以下是我想出的SQL:
FRUIT_ID BASKET_ID FRUIT_TYPE
-------- --------- ----------
2 1 Orange
5 2 Plum
除非 select fruit_id, basket_id, fruit_type
from fruit f
join (select basket_id, max(weight_in_grams) max_weight
from fruit
group by basket_id) t on f.basket_id = t.basket_id
and f.weight_in_grams = t.max_weight;
不保证是唯一的,否则可能会有效。在有重复的情况下,我想要按字母顺序排在最后的那个。
任何参赛者?
PS :我知道我可以将我的查询包装在另一个查询中,但这感觉相当混乱,所以我正在寻找的是尽可能地优化它。
答案 0 :(得分:4)
您可以使用dense_rank为每行指定数字。 partition by
创建具有自己序列的组(在本例中为每个篮子)。 order by
指定排序,因此按重量顺序排序(降序),然后排名第二。
每个篮子的第一行得到数字1.然后,包装查询以便只能选择得到数字1的行。您需要在子查询中执行此操作,因为分析函数不能用于我相信where子句,而且在having子句中都没有。
select
fruit_id, basket_id, fruit_type, weight_in_grams
from
(select
fruit_id, basket_id, fruit_type, weight_in_grams,
dense_rank() over (partition by basket_id order by weight_in_grams desc, fruit_type desc) as rank
from
fruit f)
where
rank = 1