Получить 3 лучших предмета объединения - PullRequest
0 голосов
/ 23 июня 2018

У меня есть 3 таблицы: product, category and product_category (какие товары в каждой категории).

Я бы хотел получить 3 самых дорогих продукта в каждой категории.

У меня есть это основное отношение:

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 самых дорогих в каждой категории.

В этом случае мы можем использовать любое количество объединенных таблиц, и оно может быть преобразовано в любой более сложный запрос.

Возможно ли это без цикла?

Я использую 10.2.14-MariaDB-log с этой схемой http://sqlfiddle.com/#!9/43035a

1 Ответ

0 голосов
/ 23 июня 2018

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
...