2013-11-15 211 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