我有一个跟踪共同基金投资的网站。为此,我有下面的表结构(结构已被修改,以删除不需要的列,以便把注意力集中在我的问题上)
表#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 :(得分: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...
答案 1 :(得分: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