我会亲自在 SQL 中执行此操作。您可以使用 SUM() 聚合来获取每个帐户的值。但是,您不想对百分比求和,而是希望对这些值求和,然后在获得总数后创建百分比。平均值的总和与总和的平均值不同(在某些情况下除外,但我们不能假设)。
我会做这样的事情,尽管您可能需要对其进行调整以使其正常工作。(我也可能不完全理解您使用的所有列的含义)。
SELECT PortfolioBaseCode,totalValue,cashValue,
(CAST(cashValue AS FLOAT)/totalValue) * 100 AS pcntCash
FROM (
SELECT b.PortfolioBaseCode,
SUM(a.MarketValue) AS totalValue
SUM(CASE s.SecuritySymbol WHEN 'CASH' THEN a.MarketValue ELSE 0 END) AS cashValue
FROM APXUser.fAppraisal (@ReportData) a
LEFT JOIN APXUser.vPortfolioBaseSettingEx b ON b.PortfolioBaseID = a.PortfolioBaseID
LEFT JOIN APXUser.vSecurityVariant s ON s.SecurityID = a.SecurityID
AND s.SecTypeCode = a.SecTypeCode
AND s.IsShort = a.IsShortPosition
AND a.PercentAssets >= @PercentAssets
GROUP BY b.PortfolioBaseCode
) AS t
WHERE (CAST(cashValue AS FLOAT)/totalValue)>=@pcntParameter
或者,您可以使用 HAVING 子句来过滤聚合函数,就像 WHERE 子句一样(尽管我觉得这不太可读):
SELECT b.PortfolioBaseCode,
SUM(a.MarketValue) AS totalValue
SUM(CASE s.SecuritySymbol WHEN 'CASH' THEN a.MarketValue ELSE 0 END) AS cashValue,
(SUM(a.MarketValue)/SUM(CASE s.SecuritySymbol WHEN 'CASH' THEN a.MarketValue ELSE 0 END))*100 AS cashPcnt
FROM APXUser.fAppraisal (@ReportData) a
LEFT JOIN APXUser.vPortfolioBaseSettingEx b ON b.PortfolioBaseID = a.PortfolioBaseID
LEFT JOIN APXUser.vSecurityVariant s ON s.SecurityID = a.SecurityID
AND s.SecTypeCode = a.SecTypeCode
AND s.IsShort = a.IsShortPosition
AND a.PercentAssets >= @PercentAssets
GROUP BY b.PortfolioBaseCode
HAVING (SUM(a.MarketValue)/SUM(CASE s.SecuritySymbol WHEN 'CASH' THEN a.MarketValue ELSE 0 END))>=@pcntParameter
基本上,您可以使用分组和聚合函数来获取每个帐户的总价值和现金价值,然后从中计算出适当的百分比。这将考虑到其他持股中的任何负面因素等。
聚合函数和分组的一些参考:
MSDN - 分组(TSQL)
MSDN - 聚合函数
MSDN - HAVING 子句
如果您发现需要进行某种聚合但无法对结果进行分组,您应该考虑使用非常方便的 TSQL 窗口函数:
在 SQL Server 中使用窗口函数
MSDN - OVER 子句