SQL 求和分组时连接多个表

SQL to join multiple tables while summing and grouping

我正在寻求帮助,了解如何针对多个 table 构建 MS Access SQL 查询,并总结按项目分组的结果以及不同类型的美元金额总和金融交易。

项目 table 包含有关项目的元数据。实际值、预算值和预测值 table 是针对项目的实际 and/or 计划财务交易的记录。

tables 和字段(为此 post 进行了显着简化)如下:

Project
--------------
project_id
project_name
project_manager

Budget
--------------
entry_date
project_id
amount

Actuals
--------------
entry_date
project_id
amount

Forecast
--------------
entry_date
project_id
amount

SQL 尝试:

SELECT
    p.[project_id],
    SUM(b.[amount]) AS budget_amount,
    SUM(a.[amount]) AS actual_amount,
    SUM(f.[amount]) AS forecast_amount
FROM
    Project AS p,
    Budget AS b,
    Actuals AS a,
    Forecast AS f
WHERE
    p.[project_id] = b.[project_id]
    AND b.[project_id] = a.[project_id]
    AND a.[project_id] = f.[project_id]
GROUP BY
    p.[project_id];

期望的结果:

project_id  budget_amount   actual_amount   forecast_amount
2021-001    ,000.00   ,900.00   ,400.00
2021-002    ,000.00   ,500.00   ,000.00

实际结果:

project_id  budget_amount   actual_amount   forecast_amount
2021-001    ,000.00  ,400.00  ,600.00
2021-002    ,000.00  ,000.00  ,000.00

示例数据:

项目

project_id  project_name    project_manager
2021-001    First Project of 2021   Jack Black
2021-002    Second Project of 2021  James Dean

统计数据

entry_date  project_id  amount
1/9/2021    2021-001    ,300.00
1/23/2021   2021-001    ,600.00
1/9/2021    2021-002    ,500.00
1/23/2021   2021-002    ,000.00

预算

entry_date  project_id  amount
1/9/2021    2021-001    ,000.00
1/23/2021   2021-001    ,000.00
1/9/2021    2021-002    ,500.00
1/23/2021   2021-002    ,500.00

预测

entry_date  project_id  amount
1/9/2021    2021-001    0.00
1/23/2021   2021-001    ,000.00
2/6/2021    2021-001    0.00
1/9/2021    2021-002    ,500.00
1/23/2021   2021-002    ,000.00
2/6/2021    2021-002    0.00

您需要做的是在将它们加入最终查询之前根据项目粒度独立创建每个摘要。

此更改将 运行 的所有子查询放在一个查询中。 假设 project_id 是项目 table 中的唯一键,这意味着:

SELECT
    p.[project_id],
    budget_amount,
    actual_amount,
    forecast_amount
FROM
    Project AS p left join 
    (SELECT
    [project_id],
    SUM([amount]) AS budget_amount,
FROM
    Budget
GROUP BY
    [project_id]) AS b on p.project_id=b.project_id
Left join 
    (SELECT
    [project_id],
    SUM([amount]) AS actual_amount,
FROM
    Actuals
GROUP BY
    [project_id]) AS a on p.project_id = a.project_id
Left join 
    (SELECT
    [project_id],
    SUM([amount]) AS forecast_amount,
FROM
    forecast
GROUP BY
    [project_id]) AS f on p.project_id = f.project_id

项目 table 左侧加入了所有其他摘要,因为假定它包含一个项目列表,而其他摘要中 may/may 不存在这些项目。

我真的希望有一个更优雅的方法。另外,我相当有信心有更好的方法,但这很有效,希望我能继续工作。

当然愿意接受反馈。

SELECT
    project_id,
    budget_amount,
    actual_amount,
    forecast_amount
FROM (
SELECT b.[project_id] as fs_project_id, budget_amount, actual_amount
    FROM
        (   
    SELECT
            b.[project_id],
            SUM(b.[amount]) AS budget_amount
        FROM
            Budget AS b
        GROUP BY
            b.[project_id]
    ) AS q_BudgetSum
        LEFT JOIN (
    SELECT
            a.[project_id],
            SUM(a.[amount]) AS actual_amount
        FROM
            Actuals AS a
        GROUP BY
            a.[project_id]
    ) AS q_ActualSum ON q_ActualSum.[project_id] = q_BudgetSum.[project_id]
) AS FirstSet
    LEFT JOIN
    ( SELECT p.[project_id] as project_id, forecast_amount
    FROM
        (   
    SELECT *
        FROM
            Project AS p
    ) AS q_Project
        LEFT JOIN (
    SELECT
            f.[project_id],
            SUM(f.[amount]) AS forecast_amount
        FROM
            Forecast AS f
        GROUP BY
            f.[project_id]
    ) AS q_ForecastSum ON q_ForecastSum.[project_id] = q_Project.[project_id]
)
AS SecondSet
    ON FirstSet.[fs_project_id] = SecondSet.[project_id];