2016-11-28 8 views
2

コスト計算フェーズから請求のフェーズまでの償還要求に続く複数のテーブルがあり、要求の各段階で明細とその値を記録します。mysqlの合計クエリの簡略化

各フェーズでの各経費カテゴリの合計を取得するために、私は選択を使用してそれらを合算 - 私が把握することができていないと、別のをやってすることなく、全体の相のための彼らの総計を合計するための効率的な方法であります合計要求。これは何十万行ものクエリを実行するため、応答時間が苦しいです。現在の方法は、すぐ下に4.59秒かかります - 私は壮大総和を削除すると、それは4.02秒かかりながら - 元の合計を別名する方法上の任意のアドバイスを総計を取得するために最も歓迎されるでしょう:

SELECT p.program_name, p.id as program_id, p.entity_id, a.id as account_id, 


(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 9 and c.account_id = a.id) as NIPLoanCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 2 and c.account_id = a.id) as AcquisitionCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 3 and c.account_id = a.id) as PreDemoCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 4 and c.account_id = a.id) as DemolitionCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 5 and c.account_id = a.id) as GreeningCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 6 and c.account_id = a.id) as MaintenanceCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 7 and c.account_id = a.id) as AdministrationCost, 
(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 8 and c.account_id = a.id) as OtherCost, 

(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE c.account_id = a.id) 
as TotalCost, 

/* I have removed the other 4 table's requests that follow this same methodology */ 

FROM programs p, accounts a WHERE p.entity_id = a.entity_id; 
+0

'a.entity_id'と' a.id'の関係は何ですか? –

+0

エンティティ(entity_id)は、アイテムが属するアカウント(a.id)を所有する組織です。エンティティは多くのアカウントを所有することができますが、アカウントには1つのエンティティしか持てません。 –

+0

私はあなたに以下の回答を与えました。これは少し修正する必要があります。 –

答えて

4

することができます条件付き集計を使用してcost_itemsテーブルへの結合を使用して、すべてのサブクエリを置き換えます。このような何か作業をする必要があります:あなたの独創的なアプローチとの欠陥は、このような相関サブクエリであったことを

SELECT p.program_name, 
     p.id as program_id, 
     p.entity_id, 
     t.* 
FROM programs p 
INNER JOIN accounts a 
    ON p.entity_id = a.entity_id 
INNER JOIN 
(
    SELECT a.id AS account_id, 
      SUM(CASE WHEN c.expense_category_id = 9 THEN c.amount ELSE 0 END) AS NIPLoanCost, 
      SUM(CASE WHEN c.expense_category_id = 2 THEN c.amount ELSE 0 END) AS AcquisitionCost, 
      SUM(CASE WHEN c.expense_category_id = 3 THEN c.amount ELSE 0 END) AS PreDemoCost, 
      SUM(CASE WHEN c.expense_category_id = 4 THEN c.amount ELSE 0 END) AS DemolitionCost, 
      SUM(CASE WHEN c.expense_category_id = 5 THEN c.amount ELSE 0 END) AS GreeningCost, 
      SUM(CASE WHEN c.expense_category_id = 6 THEN c.amount ELSE 0 END) AS MaintenanceCost, 
      SUM(CASE WHEN c.expense_category_id = 7 THEN c.amount ELSE 0 END) AS AdministrationCost, 
      SUM(CASE WHEN c.expense_category_id = 8 THEN c.amount ELSE 0 END) AS OtherCost, 
      COALESECE(SUM(c.amount), 0) AS TotalCost 
    FROM accounts a 
    LEFT JOIN cost_items c 
     ON a.id = c.account_id 
    GROUP BY a.id 
) t 
    ON a.id = t.account_id 

注:

(SELECT COALESCE(SUM(amount),0) FROM cost_items c WHERE expense_category_id = 9 and c.account_id = a.id) 

をすべてのレコードのためにあなたがいたprogramsaccountsテーブルの接合体で和を決定するためにcost_itemsテーブル全体をスキャンしていた別個のクエリ(実際にそれらの多く)を発行します。私のアプローチでは、accountscost_itemsの結合を1回通過し、ここで時間が保存されます。

+0

うわー...私は試してみましょう。 –

+0

ON a.id = t.idがONになっているように見えるa.id = t.account_id - その変更を行うと、合計が非常に高速になります(0.05秒)。一緒にすべてのアイテムの総計 –

+0

あなたがこれより複雑なものを望むなら、あなたは本当にあなたの質問をクリーンアップし、期待される出力とともにサンプルデータを追加すべきです。 –