Как получить категории, если в их потомках есть товар?

Собственно структура
Категории
ID   Название       Родитель
1    Категория1    null
2    Категория2    1

Товары
ID     Название     Категория
1       Товар 1        2


Соответственно нужно получить все категории, если в них и/или их потомках есть товар.
Подойдет подсказка и на Django ORM и на чистом SQL.
Спасибо!
  • Вопрос задан
  • 192 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Во-первых, для древовидных структур всегда используйте MPTT. Иначе обход дерева будет долгим, требовательным к ресурсам и зависимым от количества элементов и уровня их вложенности.

Во-вторых, ORM с этой задачей не справится. А на чистом SQL можно.
Предположим, что у нас есть приложение "catalog" и модели в нём такие:
class Category(MPTTModel):
    parent = TreeForeignKey('self', verbose_name=u'Родитель', null=True, blank=True, related_name='children')
    name = models.CharField(u'Название', max_length=100)

class Product(models.Model):
    category = TreeForeignKey(Category, verbose_name=u'Категория')
    ...

Тогда SQL-запрос будет таким:
SELECT name FROM catalog_category AS cc
INNER JOIN LATERAL (
  SELECT cc.id AS id, SUM(products) AS p_count FROM (
    SELECT cc.id AS parent_id, category_id, COUNT(id) AS products
    FROM catalog_product
    WHERE category_id IN (
      SELECT id FROM catalog_category
      WHERE lft <= cc.rght AND lft >= cc.lft AND tree_id = cc.tree_id)
      GROUP BY category_id
    ) AS sub_cс
  GROUP BY parent_id
) AS cp
USING(id) WHERE cp.p_count > 0;


Естественно, работать будет на взрослых СУБД с поддержкой современных стандартов SQL. Например, на PostgreSQL.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
syschel
@syschel
freelance/python/django/backend
Один из вариантов, взять модель товаров, сгруппировать их по категориям = список категорий.
С родителями эту уже строить деревья. Выше ты получаешь все категории у которых есть товары, дальше смотришь есть ли родитель и если есть то лезешь по дереву вверх (если структура изначально не древовидная, а глубина категорий больше 2х).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы