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

View working demo on DB Fiddle