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

时间:2016-05-18 01:39:41

标签: sql postgresql postgresql-9.3

我正在尝试使用通过line_items表关联的查询来聚合产品skus列表。我已经抽象了一个用例的简单例子:

我的预期结果如下所示:

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

3 个答案:

答案 0 :(得分:2)

您可以将相关子查询与JOIN一起使用,以获取每个sku的{​​{1}}列表

order

ONLINE DEMO

答案 1 :(得分:2)

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

答案 2 :(得分:1)

一种解决方案可能是

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