SQL 与 postgres 具有一对多关系的聚合查询

SQL aggregate query with one-to-many relationship with postgres

我正在尝试将产品 SKU 列表与通过 line_items table 相关的查询进行聚合。我已经抽象出我的用例的一个简单示例:

我的预期结果是这样的:

id  name        skus
1   mike bar    sku1,sku2,sku3
2   bort baz    sku4

给定一个架构和数据,例如:

产品

id  sku
1   sku1
2   sku2
3   sku3 
4   sku4

line_items

id  order_id    product_id
1   1           1
2   1           2
3   1           3
4   2           4

地址

id  name
1   'bill foo'
2   'mike bar'
3   'bort baz'

订单

id  address_id  total
1   2           66
2   3           99

这是一个有效的查询,但它不正确,我得到了每个订单的所有产品。我的 WHERE 应该使用 orders.id

http://sqlfiddle.com/#!15/70cd7/3/0

但是,我似乎无法使用 orders.id?我猜我需要使用 JOINLEFT JOIN 或以某种方式更改查询中事物的顺序...

http://sqlfiddle.com/#!15/70cd7/4

您可以使用带有 JOIN 的相关子查询来获取每个 order

sku 列表
SELECT
    o.id,
    a.name,
    (SELECT array_to_string(array_agg(sku), ',') AS Skus
     FROM products p
     INNER JOIN line_items li
        ON li.product_id = p.id
     WHERE li.order_id = o.id
    ) AS Skus
FROM orders o
INNER JOIN addresses a
  ON a.id = o.address_id

ONLINE DEMO

一个解决方案可能是

SELECT orders.id,
   addresses.name,
   (SELECT string_agg(sku,',') AS skus
    FROM products
    WHERE id IN
       (SELECT DISTINCT line_items.product_id
        FROM line_items
        WHERE line_items.order_id = orders.id))
FROM orders
inner join addresses
on orders.address_id = addresses.id
;

SQLFiddle

http://sqlfiddle.com/#!15/70cd7/12

SELECT orders.id,
       addresses.name,
       array_agg(DISTINCT products.sku )
FROM orders 
LEFT JOIN addresses
ON orders.address_id = addresses.id
LEFT JOIN line_items
ON line_items.order_id = orders.id
LEFT JOIN  products
ON products.id = line_items.product_id
GROUP BY orders.id,addresses.name