Получение результатов из объединений нескольких таблиц (4) с использованием SQL или кода при необходимости (python) - PullRequest
0 голосов
/ 09 мая 2018

Я работаю с PostgreSQL 10 и Python 3. Я знаю, как сделать простой выбор или объединение, купить У меня есть проблемы, когда нужно объединить 4 таблицы, связанные 2 на 2.

Я упоминаю, что я использую Phyton, на случай, если необходимо объединить запросы, используя код.

У меня есть следующие таблицы: Company, CompanyLogo, Product, ProductImage, со следующими

  1. отношений:

    • Логотип компании O1O с компанией
    • Продукт имеет FK для компании
    • ProductImage FK с продуктом
  2. Структура

    Company
    
    Id  | slug
     1     1
    

    Logo
    Id | path | company_id
    1     url        1


   -----------
    Product
    Id | company_id
    1     1
    2     1


    ProductImage

    Id | path | product_id
    1     url   1
    2     url   1 
    3     url   1

Мне нужно:

  1. Получить список всех компаний, и для каждой компании получить:

    • Слизняк компании
    • логотип
    • до 3 товаров и их первое изображение
  2. Получить одну компанию на основе идентификатора и:

    • Слизняк компании
    • логотип
    • все товары и их первое изображение

1 Ответ

0 голосов
/ 10 мая 2018

Проблема в том, что у вас есть эти ограничения на количество продуктов или изображений.

Я пытался решить эту проблему в подзапросах, выбирая только первые n продуктов / изображений для каждой компании / продукта, определяя количество младших идентификаторов. Идентификатор совпадает только в том случае, если не более чем n идентификаторов меньше или равно идентификатору для той же компании или продукта. Другими словами, продукты / изображения с n (или менее чем n , если их не больше) с самыми низкими идентификаторами для компании / продукта сделают это в результате. Для logo, если я вас правильно понял, company_id уникален, так что этот шаг там не нужен. (В случае, если я неправильно это понял, это был бы аналог подзапроса другим.) В случае изображений, которые действительно извлекают first картинку, учитывая, что ID автоматически увеличивается. Так что если «первое» в вашем вопросе нужно понимать буквально, это тоже дано.

Я предположил, что вы хотите видеть компанию / продукт, даже если для него нет логотипа / продукта / изображения. Поэтому я использовал LEFT JOIN с.

  1. Два подзапроса, один для product, один для productimage:

    SELECT c.id,
           c.slug,
           l.id,
           l.path,
           p.id,
           i.id,
           i.url
           FROM company c
                LEFT JOIN logo l
                          ON l.company_id = c.id
                LEFT JOIN (SELECT pi.id,
                                  pi.company_id
                                  FROM product pi
                                  WHERE (SELECT count(*)
                                                FROM product pii
                                                WHERE pii.company_id = pi.company_id
                                                      AND pii.id <= pi.id) <= 3) p
                          ON p.company_id = c.id
                LEFT JOIN (SELECT i.id,
                                  i.product_id,
                                  i.path
                                  FROM productimage ii
                                  WHERE (SELECT count(*)
                                                FROM productimage iii
                                                WHERE iii.product_id = ii.product_id
                                                      AND iii.id <= ii.id) <= 1) i
                          ON i.product_id = p.id;
    
  2. Один подзапрос для productimage; замените ? на соответствующий идентификатор компании:

    SELECT c.id,
           c.slug,
           l.id,
           l.path,
           p.id,
           i.id,
           i.url
           FROM company c
                LEFT JOIN logo l
                          ON l.company_id = c.id
                LEFT JOIN product p
                          ON p.company_id = c.id
                LEFT JOIN (SELECT i.id,
                                  i.product_id,
                                  i.path
                                  FROM productimage ii
                                  WHERE (SELECT count(*)
                                                FROM productimage iii
                                                WHERE iii.product_id = ii.product_id
                                                      AND iii.id <= ii.id) <= 1) i
                          ON i.product_id = p.id
           WHERE company_id = ?;
    

(не проверено, поскольку не было предоставлено ни DDL, ни DML.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...