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
?我猜我需要使用 JOIN
或 LEFT JOIN
或以某种方式更改查询中事物的顺序...
您可以使用带有 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
一个解决方案可能是
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
;
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
我正在尝试将产品 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
?我猜我需要使用 JOIN
或 LEFT JOIN
或以某种方式更改查询中事物的顺序...
您可以使用带有 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
一个解决方案可能是
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
;
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