具有匹配ID MySQL的所有相关行的总和

时间:2012-12-27 21:56:42

标签: mysql sql

我有以下表格架构:

    tbl_portfolio
    ----------
    id (auto number)
    name

-

    tbl_registration
    ----------------
    id(auto number)
    name
    portfolio_id (FK to tbl_portfolio.id)

-

    tbl_fund
    ---------
    id (auto number)
    registration_id (FK to tbl_registration.id)

-

     tbl_transaction
     ---------------
     id (auto number)
     fund_id (FK to tbl_fund.id)
     type
     shares
     price

我需要创建一个在伪代码中执行以下操作的查询:

      SELECT port.*, SUM ALL transactions for each portfolio,
      FROM tbl_portfolio port
      INNER JOIN tbl_registration reg ON reg.portfolio_id = port.id
      LEFT JOIN tbl_fund fund on fund.registration_id = reg.id
      LEFT JOIN tbl_transaction trans ON trans.fund_id = fund.id

现在当然这个查询不起作用......我基本上需要的是将每个基金的所有价格*单位加起来,然后在每次注册时将它们加在一起,然后为每个投资组合总结所有这些。

每个投资组合可以有多个注册,每个注册可以有多个基金,每个基金可以有多个交易。

最后一个在这里投掷一个粘合剂的项目,可能有10个或100个的投资组合需要计算,所以我不知道如何编写查询,更不用说以不依赖于子查询的有效方式编写它了会导致它的表现非常糟糕。

感谢您的帮助!

编辑: PinnyM的答案适用于并正确地查询数据 - 但是我应该扩展到完全需要。

除了tbl_transaction之外,还有一个tbl_distri和tbl_div。两者都将fund_id作为FK改为tbl_fund.id。我需要得到tbl_distri.amount和tbl_div.units的SUM。 因此,完整的伪问题将产生以下效果:

      SELECT port.*, SUM ALL transactions for each portfolio, SUM(div.units), SUM(distri.amount)
      FROM tbl_portfolio port
      INNER JOIN tbl_registration reg ON reg.portfolio_id = port.id
      LEFT JOIN tbl_fund fund on fund.registration_id = reg.id
      LEFT JOIN tbl_transaction trans ON trans.fund_id = fund.id
      LEFT JOIN tbl_distri distri on distri.fund_id = fund.id
      LEFT JOIN tbl_div div on div.fund_id = fund.id

2 个答案:

答案 0 :(得分:1)

您是否尝试过使用SUM()

SELECT port.*, SUM(trans.shares * trans.price) AS transaction_totals
  FROM tbl_portfolio port
  INNER JOIN tbl_registration reg ON reg.portfolio_id = port.id
  LEFT JOIN tbl_fund fund on fund.registration_id = reg.id
  LEFT JOIN tbl_transaction trans ON trans.fund_id = fund.id
  GROUP BY port.id

答案 1 :(得分:0)

从您的问题判断,您正在寻找汇总的SUM

       SELECT port.id AS port_id, 
              reg.id  AS reg_id, 
              fund.id AS fund_id,
              SUM ( trans.shares * trans.price) AS net_asset_value
         FROM tbl_portfolio port
   INNER JOIN tbl_registration reg ON reg.portfolio_id = port.id
    LEFT JOIN tbl_fund fund on fund.registration_id = reg.id
    LEFT JOIN tbl_transaction trans ON trans.fund_id = fund.id
     GROUP BY port.id, reg.id, fund.id WITH ROLLUP

这将通过id为您提供总和ID。您可以使用其他JOIN操作作为子查询来获取文本名称。

这将得到如下结果:

 port_id  reg_id  fund_id   net_asset_value
    1       1       1          150.00
    1       1       2          100.00
    1       1      NULL        250.00   (rollup of previous two lines)
    1       2       1           24.00
    1       2       4           80.00
    1       2      NULL        104.00   (rollup of previous two lines)
    1      NULL    NULL        354.00   (rollup at portfolio level)
    3       1       1           40.00
    3       1       2           50.00
    3       1      NULL         90.00   (rollup of previous two lines)
    3       2       1           14.00
    3       2       4           60.00
    3       2      NULL         74.00   (rollup of previous two lines)
    3      NULL    NULL        164.00   (rollup at portfolio level)
  NULL     NULL    NULL        518.00   (grand total)

NULL使其进入此结果集,因为这是WITH ROLLUP的作用。此结果集中只包含ID;据推测,即使名称不是,ID也是唯一的。投资组合,基金等的非唯一名称将使GROUP BY陷入困境。因此我之前关于检索名称的评论。