2

次のテーブル スキーマがあります。

    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

もちろん、そのクエリは機能しません...私が本質的に必要としているのは、各ファンドのすべての価格 * 単位を合計し、次に登録ごとにそれらを合計し、次にポートフォリオごとにそれらをすべて合計することです。

各ポートフォリオは複数の登録を持つことができ、各登録は複数のファンドを持つことができ、各ファンドは複数のトランザクションを持つことができます。

これに執着している最後の項目は、数十または数百のポートフォリオがある可能性があるため、クエリの書き方がわかりません。ましてや、それを引き起こすサブクエリに依存しない効果的な方法で書きます。パフォーマンスが著しく低下する。

お手伝いありがとう!

編集: PinnyM の回答は機能し、データを正しくクエリしますが、完全な必要性を拡張する必要があります。

tbl_transaction の他に、tbl_distri と tbl_div もあります。どちらも fund_id を tbl_fund.id への FK として持っています。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
4

2 に答える 2

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
于 2012-12-27T21:58:59.247 に答える
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)

これは WITH ROLLUP が行うことなので、NULL はこの結果セットに入ります。この結果セットには ID のみが含まれています。おそらく、名前が一意でなくても、ID は一意です。ポートフォリオ、ファンドなどの一意でない名前は、GROUP BY をかなり混乱させます。したがって、名前の取得に関する以前のコメント。

于 2012-12-27T22:09:09.153 に答える