2013-11-15 286 views
0

我有一個跟蹤共同基金投資的網站。爲了這個,我有如下表結構(結構已被修改,刪除不需要的列,以便使重點放在我的問題)需要幫助優化的sql查詢

表1:scheme_Mst

|Scheme_ID | fundHouse_Id | OpeningBalance | OpeningUnits 
---------------------------------------------------------- 
|1   | 1   | 100   | 10 

表#2投資

|Scheme_ID | InvestedAmt | InvestedUnits | statusFlag 
---------------------------------------------------------- 
|1   | 50   | 5   | A 

表#3贖回

|Scheme_ID | redemedAmt | redemedUnits | statusFlag 
---------------------------------------------------------- 
|1   | 50   | 5   | A 

表#4 SwitchDetails

|From_Scheme_ID |To_Scheme_ID |switchInAmt |switchInUnits |switchOutAmt |switchOutUnits | StaFlag 
------------------------------------------------------------------------------------------ 
|1    | 2   | 20   | 2   | 10   | 1    | A 

表#5 BonusDetails

|Scheme_ID | BonusAmt | BonusUnits | statusFlag 
---------------------------------------------------------- 
|1   | 50   | 5   | A 

表#6 Divident_Detais

|Scheme_ID | DividentAmt | DividentUnits | statusFlag 
---------------------------------------------------------- 
|1   | 50   | 5   | A 

現在擁有的在下面我有查詢方案可用單位的詳細信息......(這是非常非常昂貴)

SELECT *, 
     CASE 
      WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits) 
      ELSE 0 
     END AS WAC 
FROM 
    (SELECT *, 
      ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding, 
      ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + SNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits 
    FROM 
    (SELECT C.scheme_ID,D.schemeName, D.Openingbalance AS OpeningBalance, D.OpeningUnits AS openingUnits, ISNULL(SUM(C.invstAmount),0) AS invstAmount, ISNULL(SUM(C.invstUnits),0) AS invstUnits, 
     (SELECT ISNULL(SUM(redemedAmt),0) 
     FROM redemption 
     WHERE StatusFlag='A' 
      AND scheme_ID = C.scheme_ID) AS redeemedAmount, 
     (SELECT ISNULL(SUM(redeemedUnits),0) 
     FROM redemption 
     WHERE StatusFlag='A' 
      AND scheme_ID = C.scheme_ID) AS redeemedUnits, 
     (SELECT ISNULL(sum(switchOutAmt),0) 
     FROM SwitchDetails 
     WHERE BB.Status = 'A' 
      AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutAmount, 
     (SELECT ISNULL(sum(switchOutUnits),0) 
     FROM SwitchDetails 
     WHERE BB.Status = 'A' 
      AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedOutUnits, 
     (SELECT ISNULL(sum(switchOutAmt),0) 
     FROM SwitchDetails 
     WHERE BB.Status = 'A' 
      AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInAmount, 
     (SELECT ISNULL(sum(SwitchedInUnits),0) 
     FROM SwitchDetails 
     WHERE BB.Status = 'A' 
      AND BB.From_Scheme_Id = C.scheme_ID) AS SwitchedInUnits, .. same way 
     FOR bonus 
     AND divident .. 
     FROM Investment c) tab)tab2 

這個查詢應該產生下面的輸出。(樣本輸出)

Scheme_ID| Scheme_Name | OpeningBalance | OpeningUnits | InvstAmount | invstUnits | redemedAmount | redemedUnits | SwitchedOutAmt | SwitchOutUnit | bonusAmt | bonusUnit | DividentAmount | DividentUnit | Outstanding | OutstandingUnit | WAC 
------------------------------------------------------------------------------------------- 

這就是我計算細節的方法。請告訴我更好的方法。

我使用SQL Server 2008

+0

你需要使用連接,不允許在子查詢 – Justin

+0

的'where'每個從'SwitchedOutAmount'開始什麼都沒有做與他們引用'SwitchDetails'表的子查詢 - 這樣的數字要'sum'的整個表... – dav1dsm1th

+0

如果您有許多並行的1-N關係,那麼您可能必須使用子查詢(分組可能會重複行) - 但即使如此,您仍然可以在單個(子)查詢中彙總許多值,如「select sum()as a1, sum()as as2,... from ...「。 – Arvo

回答

0

子查詢在相同的條件可能是在這種情況下,表現最差的敵人。

試試這個你內部查詢:

SELECT 
    c.scheme_ID, 
    d.schemeName, 
    d.Openingbalance AS OpeningBalance, 
    d.OpeningUnits AS openingUnits, 
    ISNULL(SUM(c.invstAmount), 0) AS invstAmount, 
    ISNULL(SUM(c.invstUnits), 0) AS invstUnits, 

    ISNULL(SUM(r.redemedAmt), 0) AS redeemedAmount, 
    ISNULL(SUM(r.redeemedUnits), 0) AS redeemedUnits, 
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedOutAmount, 
    ISNULL(SUM(r.switchOutUnits), 0) AS SwitchedOutUnits, 
    ISNULL(SUM(r.switchOutAmt), 0) AS SwitchedInAmount, 
    ISNULL(SUM(r.SwitchedInUnits), 0) AS SwitchedInUnits 
FROM Investment AS c 
INNER JOIN redemption AS r 
    ON r.StatusFlag='A' AND r.scheme_ID = C.scheme_ID 
--INNER JOIN someTable AS d... 
0

你可以做這樣的事情(我沒插入GROUP BY條款或總結您更好地瞭解您的查詢邏輯Openingbalance, OpeningUnits,我編輯只爲性能):

SELECT *, 
     CASE 
      WHEN OutstandingUnits <> 0 THEN CONVERT(decimal(18,2),Outstanding/OutstandingUnits) 
      ELSE 0 
     END AS WAC 
FROM 
    (SELECT C.scheme_ID, 
      D.schemeName, 
      D.Openingbalance AS OpeningBalance, 
      D.OpeningUnits AS openingUnits, 
      ISNULL(SUM(C.invstAmount),0) AS invstAmount, 
      ISNULL(SUM(C.invstUnits),0) AS invstUnits, 
     ISNULL(SUM(r.redemedAmt),0) redeemedAmount, 
     ISNULL(SUM(r.redeemedUnits),0) redeemedUnits, 
     ISNULL(sum(sd.switchOutAmt),0) SwitchedOutAmount, 
     ISNULL(sum(sd.switchOutUnits),0) SwitchedOutUnits, 
     ISNULL(sum(sd.switchOutAmt),0) SwitchedInAmount, 
     ISNULL(sum(sd.SwitchedInUnits),0) SwitchedInUnits, 
      --The sum columns from above query 
      ISNULL(OpeningBalance,0) + ISNULL(DividendAmount,0) + ISNULL(bonusAmount,0) + ISNULL(invstAmount,0) + 
      ISNULL(SwitchedInAmount,0) - ISNULL(redeemedAmount,0) - ISNULL(SwitchedOutAmount,0) AS Outstanding, 
      ISNULL(openingUnits,0) + ISNULL(DividendUnits,0) + ISNULL(bonusUnits,0) + ISNULL(invstUnits,0) + 
      ISNULL(SwitchedInUnits,0) - ISNULL(redeemedUnits,0) - ISNULL(SwitchedOutUnits,0) AS OutstandingUnits, 
      ---- 
     .. same way 
     FOR bonus 
     AND divident .. 
     FROM Investment c 
     LEFT JOIN redemption r 
     ON r.StatusFlag='A' 
     AND r.scheme_ID = C.scheme_ID 
     LEFT JOIN SwitchDetails sd 
     ON sd.Status = 'A' 
     AND sd.From_Scheme_Id = C.scheme_ID 
     ) tab