Как правильно написать sql запрос агрегации для фасетного фильтра?

Ссылка скопирована
1 ответ

Предыстория:
Делаю пет проект магазина с возможностью фильтрации товаров по десяткам атрибутов. Я понятия не имею как это должно делаться и детальной информации мне найти не удалось, поэтому делал так как получилось. Создал базу данных следующей структуры (как позже выяснилось это называется EAV модель)

Как правильно написать sql запрос агрегации для фасетного фильтра?

Мне необходимо создать запрос получающий все атрибуты конкретной категории со всеми имеющимся опциями для этого атрибута и количеством товаров для каждой опции каждого атрибута.

Первую половину я получил

Как правильно написать sql запрос агрегации для фасетного фильтра?

Теперь мне надо получить третью колонку с количеством товаров и не знаю как мне это правильно написать.

Обновление:
У меня получился следующий sql

SELECT a.id as attr_id, a.alias as attr_alias, a.name as attr_name, o.id as option_id, o.alias as option_alias, o.value as option_value, COUNT(pp.product_id) AS prod_count FROM "Product" p  JOIN "Product_property" pp on pp.product_id = p.id JOIN "Attribute" a ON pp.attribute_alias  = a.alias JOIN "Option" o ON pp.option_id  = o.id where p.cat_id = 1 GROUP BY a.id, a.name, a.alias, o.id, o.alias, o.value

SELECT a.id as attr_id, a.alias as attr_alias, a.name as attr_name, o.id as option_id, o.alias as option_alias, o.value as option_value, COUNT(pp.product_id) AS prod_count FROM "Product" p JOIN "Product_property" pp on pp.product_id = p.id JOIN "Attribute" a ON pp.attribute_alias = a.alias JOIN "Option" o ON pp.option_id = o.id where p.cat_id = 1 GROUP BY a.id, a.name, a.alias, o.id, o.alias, o.value

Дополнительно:

1. Заготовку запроса в текстовом виде вставьте в вопрос.
2. Описание таблиц с полями тоже в текстовом виде представьте.
Никто в здравом уме не будет ручками это переписывать, чтобы вам помочь.

  • Создал базу данных следующей структуры

    Ну кривая же структура, ёлки-палки...

    Что за таблица attr_options? в чём её смысл? Если по схеме - скорее всего, она формирует возможные пары... но ничто не мешает в таблице property иметь невозможную пару. А если на неё возлагается какой-то иной смысл, то скорее всего она вообще не нужна.

  • Ну кривая же структура, ёлки-палки...

    Akina, чтобы не было таких претензий, я написал предысторию. Я понятия не имею как правильно (информации о об этом в прикладном плане нет), по этому делал как получится, я даже только потом узнал, что это кто-то называет это EAV моделью, а то что мне нужно реализовать оказывается называется фасетный поиск, прикладной информации о котором тоже нет )

  • Barancheek, я написал это к тому, что на неправильной структуре проблемы будут только копиться. Гораздо лучше сейчас, пока ещё не поздно, пересмотреть структуру и сделать её не по некоему мистическому наитию, а изучить вопрос (анализ предметной области, построение ER-диаграммы) и уже на основе полученных знаний заново создать структуру. На которой большинство типовых задач (а фасетный поиск - задача типовая) давно решены и даже оптимизированы.
  • Что-то для EAV у тебя дофига таблиц. Можно ли слегонца их уменьшить число.?

    Вот я реально не уверен что в них есть польза.

  • Akina, я не знаю как найти чёткий структурированный материал по всей этой теме ни в Гугле, ни на github, ни в ChatGPT.
  • Barancheek, https://habr.com/ru/search/?q=eav&target_type=post...
  • Barancheek,

    я не знаю как найти чёткий структурированный материал по всей этой теме

    STFW "проектирование базы данных".

  • Нужно решить такую задачу?

    Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

    Заказать помощь
    Лучший ответ
    1
    Антон С. Ответ

    Для написания SQL запроса агрегации для фасетного фильтра вам необходимо использовать операторы GROUP BY, COUNT и JOIN. Фасетный фильтр представляет собой набор категорий или значений, по которым пользователь может фильтровать данные.

    Прежде всего, вам необходимо определить, по какому полю вы будете проводить агрегацию. Предположим, у вас есть таблица "products" с полями "category" и "price". Вы хотите посчитать количество продуктов в каждой категории.

    Пример SQL запроса для этой задачи:

    SELECT category, COUNT(*) AS product_count
    FROM products
    GROUP BY category;

    SELECT category, COUNT(*) as product_count FROM products GROUP BY category;

    В данном запросе мы выбираем поле "category" из таблицы "products", затем с помощью функции COUNT(*) подсчитываем количество записей в каждой категории. Оператор GROUP BY группирует результаты по полю "category".

    Если вы хотите добавить условие фильтрации по цене, можно воспользоваться оператором HAVING:

    SELECT category, COUNT(*) AS product_count
    FROM products
    WHERE price > 100
    GROUP BY category
    HAVING COUNT(*) > 5;

    SELECT category, COUNT(*) as product_count FROM products WHERE price > 100 GROUP BY category HAVING COUNT(*) > 5;

    В данном запросе мы добавили условие WHERE для фильтрации продуктов с ценой выше 100, затем используем оператор HAVING для отображения только категорий, в которых количество продуктов больше 5.

    Не забывайте, что для эффективной работы с фасетными фильтрами рекомендуется создание индексов на поля, по которым вы будете проводить агрегацию, чтобы ускорить выполнение запросов.

    Надеюсь, данное объяснение поможет вам правильно написать SQL запрос агрегации для фасетного фильтра. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их.

    Другие ответы (0)

    Пока нет других ответов. Будьте первым, кто поможет автору.

    Ответить на вопрос

    комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    Вам также может быть интересно