0

我正在使用 Visual Studio 2010 和 SQL Server 2012。

我搜索了网络和 stackoverflow 档案,发现其他一些人遇到了这个问题,但我无法让他们的解决方案为我工作。该问题涉及使用用户可定义的报告参数基于数据集的聚合值进行过滤。

我有以下报告。

SSRS1

该报告的最终目标是过滤具有用户可定义的现金百分比作为总资产百分比的投资组合。默认值为 30% 或更大。因此,例如,如果投资组合的总市值为 100,000 美元,其现金资产类别为 40,000 美元,这将是 40% 的现金百分比,并且该投资组合将出现在报告中。

我已经能够使用数据集本身的过滤器仅选择现金资产类别,因此这不是问题。我很容易地在数据集中添加了一个现金百分比参数,但很快意识到这是对行详细信息而不是汇总金额进行过滤,有时投资组合有多个现金账户。我需要所有现金账户的总和,这样我才能真正知道现金是否占总市值的 30% 或更大。

起初我认为报告工作正常。

SSRS2

但在将其与另一份报告进行交叉引用后,我意识到这个投资组合只有 2.66%的总现金,因为它在第二个现金账户中也有很大的负余额。这是我关心的所有现金账户的总和。

SSRS3

我想根据总行而不是详细行过滤具有 >= 现金的投资组合。我怀疑我可能需要使用标量函数 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

谢谢

4

1 回答 1

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

基本上,您可以使用分组和聚合函数来获取每个帐户的总价值和现金价值,然后从中计算出适当的百分比。这将考虑到其他持股中的任何负面因素等。

聚合函数和分组的一些参考:

MSDN - 分组(TSQL)

MSDN - 聚合函数

MSDN - HAVING 子句

如果您发现需要进行某种聚合但无法对结果进行分组,您应该考虑使用非常方便的 TSQL 窗口函数:

在 SQL Server 中使用窗口函数

MSDN - OVER 子句

于 2013-10-04T04:36:27.573 回答