我正在使用Visual Studio 2010和SQL Server 2012.
我搜索了网络和stackoverflow档案,发现其他一些人遇到了这个问题,但我无法让他们的解决方案为我工作。问题涉及使用用户可定义的报告参数基于数据集的聚合值进行过滤。
我有以下报告。
本报告的最终目标是过滤具有用户可定义现金百分比的投资组合占总资产的百分比。默认值为30%或更高。因此,例如,如果投资组合的总市值为100,000美元,而他们的现金资产类别为40,000美元,那么这将是40%的现金价值,该投资组合将出现在报告中。
我已经能够使用数据集本身的过滤器来选择现金资产类,因此这不是问题。我很容易在数据集中添加了现金百分比参数,但很快意识到这是对行详细信息而不是汇总金额的过滤,有时投资组合有多个现金账户。我需要所有现金账户的总和,这样我才能真正知道现金是否占总市值的30%或更多。
起初我认为报告工作正常。
但在对另一份报告进行交叉引用之后,我发现这个投资组合只有2.66%总现金,因为它在第二个现金账户中也有很大的负余额。这是我关心的所有现金账户的总和。
我想基于总线而不是细节线来过滤具有> =现金的投资组合。我怀疑我可能需要使用标量函数SUM()然后构建一个参数来改变数据集,但我没有成功编写查询来做到这一点。我也非常有兴趣知道这是否可以在.rdl层而不是在sql数据集级别完成。这方面的SQL有点复杂,因为报告的程序需要使用SQL函数,存储过程和参数。
如果解决方案涉及改变查询以在数据集本身中包含sum(),我怀疑它是第20行需要求和
a.PercentAssets,
以下是报告的数据集。
https://www.dropbox.com/s/bafdo2i6pfvdkk4/CashPercentDataSet.sql
这是.rdl文件。
https://www.dropbox.com/s/htg09ypyh7f1a98/cashpercent2.rdl
谢谢
答案 0 :(得分:1)
我会亲自在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
基本上,您可以使用分组和汇总功能来获取每个帐户的总价值和现金值,然后从中计算出适当的百分比。这将考虑其他财产中的任何负面因素。
聚合函数和分组的一些参考:
如果您发现需要进行某种聚合,但无法对结果进行分组,则应考虑使用非常方便的TSQL窗口函数: