SQL - GROUP BY 和 SUM 使用连接的 table 字段
SQL - GROUP BY and SUM using joined table fields
假设有两个不同的表:
包裹
id
--
1
2
3
产品
id | package_id | currency | total
----------------------------------
1 | 1 | USD | 100
2 | 1 | EUR | 200
3 | 2 | USD | 300
4 | 2 | USD | 400
5 | 3 | GBP | 500
并且期望的结果是通过每种 DISTINCT 货币获得每个包裹(从其产品)的串联总金额,例如:
id | total_amount
----------------------
1 | USD 100, EUR 200
2 | USD 700
3 | GBP 500
尝试过此查询:
SELECT
packages.id,
(
SELECT
GROUP_CONCAT(CONCAT(currency,' ',total))
FROM
(
SELECT
products.currency AS currency,
SUM(products.total) AS total
FROM products
WHERE products.package_id = [[ packages.id ]] -- double brackets just for marking
GROUP BY products.currency
) T
) AS total_amount
FROM packages
LEFT JOIN products
ON products.package_id = packages.id
GROUP BY packages.id;
但是有一个错误是package.id(在上面的双括号中)不可见,可能是因为子查询深度。
有什么方法可以实现吗?谢谢。
尝试使用 alias
作为表名来识别...
SELECT
pkg.id,
(
SELECT
GROUP_CONCAT(CONCAT(currency,' ',total))
FROM
(
SELECT
products.currency AS currency,
SUM(products.total) AS total
FROM products
WHERE products.package_id = pkg.id
GROUP BY products.currency
) T
) AS total_amount
FROM packages as pkg
LEFT JOIN products
ON products.package_id = pkg.id
GROUP BY pkg.id;
您可以使用:
select package_id , group_concat(concat(currency,' ',grandtotal))
from (
select package_id,currency, sum(total) grandtotal
from products
group by package_id,currency
) t group by package_id
db<>fiddle here
您可以尝试将查询重写为左联接而不是子查询,子查询可能 more efficient or faster 如下所示:
SELECT
p.id,
ct.currency_totals
FROM
packages p
LEFT JOIN (
SELECT
package_id,
GROUP_CONCAT(
CONCAT(currency,' ',total)
) as currency_totals
FROM (
SELECT
package_id,
currency,
SUM(total) as total
FROM
products
GROUP BY
package_id,
currency
) t
GROUP BY
package_id
) ct on ct.package_id=p.id;
id
currency_totals
1
USD 100,EUR 200
2
USD 700
3
GBP 500
此外,如果您只需要当前使用的包的包 ID 而不需要其他详细信息,则使用您的子查询可能足以完成此任务。
SELECT
package_id,
GROUP_CONCAT(
CONCAT(currency,' ',total)
) as currency_totals
FROM (
SELECT
package_id,
currency,
SUM(total) as total
FROM
products
GROUP BY
package_id,
currency
) t
GROUP BY
package_id;
package_id
currency_totals
1
USD 100,EUR 200
2
USD 700
3
GBP 500
假设有两个不同的表:
包裹
id
--
1
2
3
产品
id | package_id | currency | total
----------------------------------
1 | 1 | USD | 100
2 | 1 | EUR | 200
3 | 2 | USD | 300
4 | 2 | USD | 400
5 | 3 | GBP | 500
并且期望的结果是通过每种 DISTINCT 货币获得每个包裹(从其产品)的串联总金额,例如:
id | total_amount
----------------------
1 | USD 100, EUR 200
2 | USD 700
3 | GBP 500
尝试过此查询:
SELECT
packages.id,
(
SELECT
GROUP_CONCAT(CONCAT(currency,' ',total))
FROM
(
SELECT
products.currency AS currency,
SUM(products.total) AS total
FROM products
WHERE products.package_id = [[ packages.id ]] -- double brackets just for marking
GROUP BY products.currency
) T
) AS total_amount
FROM packages
LEFT JOIN products
ON products.package_id = packages.id
GROUP BY packages.id;
但是有一个错误是package.id(在上面的双括号中)不可见,可能是因为子查询深度。
有什么方法可以实现吗?谢谢。
尝试使用 alias
作为表名来识别...
SELECT
pkg.id,
(
SELECT
GROUP_CONCAT(CONCAT(currency,' ',total))
FROM
(
SELECT
products.currency AS currency,
SUM(products.total) AS total
FROM products
WHERE products.package_id = pkg.id
GROUP BY products.currency
) T
) AS total_amount
FROM packages as pkg
LEFT JOIN products
ON products.package_id = pkg.id
GROUP BY pkg.id;
您可以使用:
select package_id , group_concat(concat(currency,' ',grandtotal))
from (
select package_id,currency, sum(total) grandtotal
from products
group by package_id,currency
) t group by package_id
db<>fiddle here
您可以尝试将查询重写为左联接而不是子查询,子查询可能 more efficient or faster 如下所示:
SELECT
p.id,
ct.currency_totals
FROM
packages p
LEFT JOIN (
SELECT
package_id,
GROUP_CONCAT(
CONCAT(currency,' ',total)
) as currency_totals
FROM (
SELECT
package_id,
currency,
SUM(total) as total
FROM
products
GROUP BY
package_id,
currency
) t
GROUP BY
package_id
) ct on ct.package_id=p.id;
id | currency_totals |
---|---|
1 | USD 100,EUR 200 |
2 | USD 700 |
3 | GBP 500 |
此外,如果您只需要当前使用的包的包 ID 而不需要其他详细信息,则使用您的子查询可能足以完成此任务。
SELECT
package_id,
GROUP_CONCAT(
CONCAT(currency,' ',total)
) as currency_totals
FROM (
SELECT
package_id,
currency,
SUM(total) as total
FROM
products
GROUP BY
package_id,
currency
) t
GROUP BY
package_id;
package_id | currency_totals |
---|---|
1 | USD 100,EUR 200 |
2 | USD 700 |
3 | GBP 500 |