MYSQL:多个连接

ASL*_*LSW 1 mysql join

我正在尝试将一个简单的预算和费用跟踪工具与三个表组合在一起.

很简单,有一个预算表,其中包括预算名称和预算金额.

有一张承诺的表格,每个承诺都有一个数字(用于参考),金额和预算的名称.

第三个表格包含实际费用的详细信息,费用的预算名称和费用金额.如果费用与承诺相关联,则也可以使用承诺编号.

总之,规则是:

  • 每项承诺都必须与预算相对应,尽管并非每项预算都有承诺,
  • 每项费用必须与预算相对应,
  • 并非所有费用都是违背承诺的,
  • 预算可能有费用但没有承诺,
  • 承诺可能还没有针对它发布的费用,并且
  • 所有金额都汇总.

我试图产生的结果是一份报告,显示每个预算,发布给它的费用总额以及发布到该预算的总额(承诺减去承诺中的费用).

我可以(1)将预算与费用联系起来,或(2)将预算与承诺联系起来.但是我无法将这三者联系起来以产生正确的结果 - 我最终得到了巨额资金,因为每项费用都是针对每一项承诺而展示的.

我已经看了很多这里的例子(并且会继续寻找),但是理解所呈现内容的实际工作现在还有点超出我的意义.

而不是有人把一个完全工作的解决方案(我真的不希望)放在一起,有人可以提供一个简单的解释,如何获得以下结果:

  • 表1:预算 - >每行出现
  • 表2:费用 - >按预算汇总,其中预算存在费用
  • 表3:剩余承诺 - >按预算汇总,承诺存在,减去费用已记入承诺的费用.

我很高兴发布我的数据库结构,但坦率地说,我已经在几小时内为此工作了,目前还没有多少展示!

[编辑]最终结果应该是(使用mellamokb建议的样本结构):

Budget item    Budget amount     Expenses     Remaining commitment
IT             5000              390          770 
Admin          1000              250          20
Tech           300               100          0
Development    9000              350          0
Run Code Online (Sandbox Code Playgroud)

mel*_*okb 10

使用我从描述中建模的以下DB结构(我意识到这个结构没有规范化 - 我尽可能地尝试模仿OP给出的描述):

  • 预算:ID(PK),名称,金额
  • 承诺:ID(PK),RefNumber,预算,金额
  • 费用:ID(PK),预算,金额,RefNumber(可以为NULL)

以下是我用于以下示例的示例数据(以千计).

预算:

ID  Name        Amount
1   IT          5000
2   Admin       1000
3   Tech        300
4   Development 9000
Run Code Online (Sandbox Code Playgroud)

承诺:

ID  RefNumber   Budget  Amount
1   SYSUPGRADE  IT      750.00
2   PHONES      Admin   35.00
3   WINDOWS7    IT      300.00
Run Code Online (Sandbox Code Playgroud)

费用:

ID  Budget      Amount      RefNumber
1   IT          35.00       NULL
2   IT          65.00       NULL
3   IT          125.00      SYSUPGRADE
4   IT          80.00       SYSUPGRADE
5   Tech        25.00       NULL
6   Tech        75.00       NULL
7   Admin       90.00       NULL
8   Development 300.00      NULL
9   Development 50.00       NULL
10  Admin       10.00       PHONES
11  Admin       5.00        PHONES
12  Admin       12.00       NULL
13  Admin       133.00      NULL
14  IT          25.00       WINDOWS7
15  IT          60.00       WINDOWS7
Run Code Online (Sandbox Code Playgroud)

以下是满足您的三个Table示例的查询.

表1:预算 - >每行出现

select
    Name, Amount
from
    Budget B
Run Code Online (Sandbox Code Playgroud)

输出:

Name        Amount
IT          5000.00
Admin       1000.00
Tech        300.00
Development 9000.00
Run Code Online (Sandbox Code Playgroud)

表2:费用 - >按预算汇总,其中预算存在费用

select
    Budget, sum(Amount) As Amount
from
    Expense E
group by
    Budget
Run Code Online (Sandbox Code Playgroud)

输出:

Budget      Amount
Admin       250.00
Development 350.00
IT          390.00
Tech        100.00
Run Code Online (Sandbox Code Playgroud)

表3:剩余承诺 - >按预算汇总,承诺存在,减去费用已记入承诺的费用.

select
    C.Budget, T.Amount - SUM(E.Amount) as RemainingCommitmentAmount
from
    Commitment C
inner join
    Expense E on C.RefNumber = E.RefNumber
inner join
    (select Budget, SUM(Amount) as Amount from Commitment C group by Budget) T
        on T.Budget = C.Budget
group by
    C.Budget, T.Amount
Run Code Online (Sandbox Code Playgroud)

输出:

Budget  RemainingCommitmentAmount
Admin   20.00
IT      760.00
Run Code Online (Sandbox Code Playgroud)

编辑:将它们组合成单个输出就像将三个结果连接在一起一样简单.由于我们希望显示所有预算,我们将其用作基本查询,但由于可能存在或可能不存在相关费用或承诺,我们希望使用左连接加入其他结果.此外,我们将使用该COALESCE命令将NULL值替换为0.以下是查询的外观:

select
    B.Name as `Budget Item`,
    B.Amount as `Budget amount`,
    COALESCE(E.Amount, 0) as `Expenses`,
    COALESCE(C.RemainingCommitmentAmount, 0) as `Remaining commitment`
from
    (
        select
            Name, Amount
        from
            Budget B
    ) B
left join
    (
        select
            Budget, sum(Amount) As Amount
        from
            Expense E
        group by
            Budget
    ) E on B.Name = E.Budget
left join
    (
        select
            C.Budget, T.Amount - SUM(E.Amount) as RemainingCommitmentAmount
        from
            Commitment C
        inner join
            Expense E on C.RefNumber = E.RefNumber
        inner join
            (select Budget, SUM(Amount) as Amount from Commitment C group by Budget) T
                on T.Budget = C.Budget
        group by
            C.Budget, T.Amount
    ) C on C.Budget = B.Name
Run Code Online (Sandbox Code Playgroud)

输出:

Budget item Budget amount   Expenses    Remaining commitment
IT          5000.00         390.00      760.00
Admin       1000.00         250.00      20.00
Tech        300.00          100.00      0.00
Development 9000.00         350.00      0.00
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!