获取联接的前三项

时间:2018-06-23 10:37:20

标签: mysql join mariadb greatest-n-per-group

我有3张桌子: 产品,类别和product_category(每个类别中的产品)。

我想获得每个类别中最贵的前三名产品。

我有这个基本关系:

select c.name
     , p.id
     , p.price 
  from category c
  left 
  join product_category pc
    on pc.category_id = category.id
  left 
  join product p 
    on pc.product_id = p.id

但是现在我只想获取每个类别中3个最昂贵的商品。

在这种情况下,我们可以使用任意数量的联接表,并且可以将其升级为任何更复杂的查询。

有可能没有循环吗?

我正在使用具有此架构http://sqlfiddle.com/#!9/43035a的10.2.14-MariaDB日志

1 个答案:

答案 0 :(得分:2)

MySQL 8.0+和MariaDB 10.2+支持适合您的情况的窗口功能,例如dense_rank。对于每个类别,我们根据产品价格分配排名,并仅拉那些排名前3位的产品。使用dense_rank可以正确处理联系,这意味着,如果某个类别的产品具有相同的价格,则可以有更多的联系特定类别的输出中超过3行。如果这种行为不是您所希望的,并且您希望在输出中看到最多3行,并丢弃领带,请使用row_number窗口函数。

select name, id
from (
  select c.name, p.id, dense_rank() over (partition by c.id order by p.price desc) as rank
  from category c
  left join product_category pc on pc.category_id = c.id
  left join product p on pc.product_id = p.id
) t
where rank <= 3