MYSQL:多个连接

时间:2011-09-26 21:13:55

标签: 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

1 个答案:

答案 0 :(得分:10)

使用我从描述中建模的以下数据库结构(我意识到这个结构没有规范化 - 我尽可能地尝试模仿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

承诺:

ID  RefNumber   Budget  Amount
1   SYSUPGRADE  IT      750.00
2   PHONES      Admin   35.00
3   WINDOWS7    IT      300.00

费用:

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

以下是满足您的三个表示例的查询。

表1:预算 - >要出现的每一行

select
    Name, Amount
from
    Budget B

输出:

Name        Amount
IT          5000.00
Admin       1000.00
Tech        300.00
Development 9000.00

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

select
    Budget, sum(Amount) As Amount
from
    Expense E
group by
    Budget

输出:

Budget      Amount
Admin       250.00
Development 350.00
IT          390.00
Tech        100.00

表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

输出:

Budget  RemainingCommitmentAmount
Admin   20.00
IT      760.00

编辑:将它们组合成单个输出就像将三个结果连接在一起一样简单。由于我们希望显示所有预算,我们将其用作基本查询,但由于可能存在或可能不存在相关费用或承诺,我们希望使用左连接加入其他结果。此外,我们将使用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

输出:

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

希望这有帮助!