Postgresql запрос с двойными отношениями has_many - PullRequest
0 голосов
/ 01 августа 2020

У меня сложная взаимосвязь данных.

POSTGRESQL FIDDLE: https://www.db-fiddle.com/f/vm2z8qLuddzcHEgyaMnCbc/3

«Группа элементов» имеет много «элементов» через таблицу «item_ads» . Таким образом, в группе товаров много part_number.

enter image description here

reports table contains the number of clicks for each day for each adgroupid.

Each adgroupid has_many part_numbers. (table: product_ads)

enter image description here

Now, I want to SUM all reports.clicks for each item_groups.id using the part_number to linked the tables.

After this, I have to consider only reports.adgroupid which are included in the part_numbers of item_group. So if "Item group" has three part_number (A, B, C) can be considered all adgroupid that contains A,B, or C but nothing more. If adgroupid contains part_number D it cannot be considered for clicks sum.

Expected results

введите описание изображения здесь

Мне нужна таблица с множеством item_group_ids. Я ищу запрос PostgreSQL для получения этой таблицы.

1 Ответ

3 голосов
/ 02 августа 2020

Сначала давайте построим запрос по частям. Похоже, вы уже знаете, как добраться от item_group и adgroup до part_number, но не о том, как к ним присоединиться. Я добавил запрос, который удаляет дубликаты для части 1 вашего вопроса, но помещает их в CTE :

WITH unique_part_numbers AS (
  SELECT DISTINCT item_groups.id AS item_group_id,
                  part_number
  FROM item_groups
  JOIN item_ads ON item_group_id = item_groups.id
  JOIN items ON items.id = item_ads.item_id
)
SELECT unique_part_numbers.item_group_id, SUM(clicks)
FROM unique_part_numbers
JOIN product_ads ON product_ads.part_number = unique_part_numbers.part_number
JOIN reports ON product_ads.adgroupid = reports.adgroupid
GROUP BY item_group_id

По поводу второй части - это невозможно сделать как вы хотите, потому что у вас может быть несколько групп объявлений для каждой item_group, поэтому я добавил adgroupid в качестве дополнительного столбца. Я создаю массив part_numbers для группы объявлений и проверяю с помощью оператора @> , что все части, которые относятся к adgroupid, также относятся к unique_part_numbers.item_group_id.

WITH unique_part_numbers AS (
  SELECT DISTINCT item_groups.id AS item_group_id,
                  part_number
  FROM item_groups
  JOIN item_ads ON item_group_id = item_groups.id
  JOIN items ON items.id = item_ads.item_id
)
SELECT unique_part_numbers.item_group_id,
       product_ads.adgroupid,
       array_agg(unique_part_numbers.part_number),
       SUM(clicks)
FROM unique_part_numbers
JOIN product_ads ON product_ads.part_number = unique_part_numbers.part_number
JOIN reports ON product_ads.adgroupid = reports.adgroupid
GROUP BY item_group_id, product_ads.adgroupid
HAVING array_agg(product_ads.part_number) @> (
  SELECT ARRAY_AGG(other_product_ads.part_number)
  FROM product_ads AS other_product_ads
  WHERE other_product_ads.adgroupid = product_ads.adgroupid
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...