【问题标题】:Geeting results from multipe(4) tables joins using SQL or code if needed (python)如果需要,使用 SQL 或代码从多个 (4) 表连接中获取结果 (python)
【发布时间】:2018-05-09 16:34:43
【问题描述】:

我正在使用 PostgreSQL 10 和 Python 3。我知道如何进行简单的选择或连接,当我需要将 4 个相关的表 2 2 组合在一起时遇到问题。

我提到,我使用 Phyton,以防有必要使用代码组合查询。

我有以下表格:Company、CompanyLogo、Product、ProductImage,以及以下表格

  1. 关系:

    • Company Logo O1O with Company
    • 产品对公司有 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. 根据 id 获取一家公司,并且:

    • 公司蛞蝓
    • 徽标
    • 所有产品及其第一张图片

【问题讨论】:

  • 与python有什么关系?
  • @KaushikNayak 如果需要单独的查询来使用代码组合它们;出于速度考虑,或者仅使用 SQL 是不可能的

标签: python sql python-3.x postgresql join


【解决方案1】:

这里的问题是,您对产品或图像的数量有这个限制。

我尝试通过确定较低 ID 的计数,在子查询中仅选择每个公司/产品的前 n 个产品/图片来解决此问题。仅当小于或等于同一公司或产品的 ID 的 ID 不超过 n 个时,ID 才匹配。换句话说,每个公司/产品具有 n(或小于 n,如果没有更多)最低 ID 的产品/图像将出现在结果中。对于logo,如果我没听错的话,company_id 是独一无二的,所以那里不需要这一步。 (如果我误解了,这将是一个类似于其他人的子查询。)如果图片确实获取了 first 图片,假设 ID 会自动递增。因此,如果您的问题中的“第一”必须按字面意思理解,那也是如此。

我假设您甚至想查看一家公司/产品,即使它没有徽标/产品/图片。所以我使用了LEFT JOINs。

  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 的一个子查询;将 ? 替换为相应的公司 ID:

    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。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多