如何获得一个独特的价值,然后由它分组?

时间:2016-06-13 17:43:47

标签: sql sql-server reporting-services ssrs-2008

我试图通过SSRS获取不同的记录而不是查询,然后根据不同的值对数据求和。我正在SSRS数据集中执行存储过程来获取数据。以下是proc的结果:

Company ProductID PayeeID PayeeName GroupID Profit
ABC     123       1       Brenda     1a      $30
ABC     123       1       Brenda     1a      $30
ABC     123       1       Brenda     1b      $30
ABC     456       2       Diana      2a      $45
ABC     456       2       Diana      2a      $45
ABC     789       3       Jonathan   3a      $23
ABC     789       3       Jonathan   3a      $23
ABC     789       3       Jonathan   3b      $23
ABC     789       3       Jonathan   3b      $23

我需要做的是为独特的公司,产品,收款人和非组合ID分组和汇总利润。正如您所看到的那样,重复的组ID。我想要那个独特的记录。我已经在SSRS中设置了所有分组,但不知道如何使其与GroupID不同,因此我的结果在SSRS中显示如下:

Company ProductID PayeeID PayeeName Profit
ABC     123       1       Brenda    $90     =(1a+1a+1b)
ABC     456       2       Diana     $90
ABC     789       3       Jonathan  $92

**不应该是重复GroupID的SUM值

我想要的是什么:

Company ProductID PayeeID PayeeName Profit
ABC     123       1       Brenda    $60     =(1a+1b)
ABC     456       2       Diana     $45
ABC     789       3       Jonathan  $46

**不要求重复值

有关如何在SSRS中执行此操作而不在查询级别上的任何想法?我不想在查询级别上的原因是因为我必须创建一个表,执行proc并将其数据存储在我创建的表中。将来,如果修改了存储过程结构,那么我必须在两个地方修改报告才能工作。任何帮助将不胜感激,谢谢!

3 个答案:

答案 0 :(得分:3)

您可以尝试以下操作:

SELECT Company, ProductID, PayeeID, PayeeName, SUM(Profit) as Profit
FROM (SELECT DISTINCT * FROM Table_1) as t
GROUP BY Company, ProductID, PayeeID, PayeeName;

答案 1 :(得分:0)

1)如果可以接受,我会在同一个存储过程中计算这个新列的值:

SELECT a.*, 
    SUM(CASE WHEN RowNum = 1 THEN Profit END)
    OVER(PARTITION BY a.Company/*or CompanyID ?*/, ProductID, PayeeID) AS SumOfProfit
FROM (
    SELECT ..., -- Plus one more column
        ROW_NUMBER() OVER(PARTITION BY a.Company/*or CompanyID ?*/, ProductID, PayeeID, GroupID ORDER BY @@SPID) AS RowNum
    FROM ... final query from stored procedure ...
    ....
) a

基本上,这会向原始数据集添加新列(SumOfProfit)(!)

Company ProductID PayeeID PayeeName GroupID Profit SumOfProfit
ABC     123       1       Brenda     1a      $30   60
ABC     123       1       Brenda     1a      $30   60
ABC     123       1       Brenda     1b      $30   60
ABC     456       2       Diana      2a      $45   ...
ABC     456       2       Diana      2a      $45
ABC     789       3       Jonathan   3a      $23
ABC     789       3       Jonathan   3a      $23
ABC     789       3       Jonathan   3b      $23
ABC     789       3       Jonathan   3b      $23

2)第二种解决方案是将(何时可能)存储过程转换为用户定义的函数

  • 多步UDF功能(如果有两行或更多行)或
  • 内联UDF函数(如果它只有一行;注意:有时可以将多行存储过程转换为{inline | single line}函数)

然后我会改变存储过程:

ALTER PROCEDURE ...
AS
BEGIN
    SELECT f....
    FROM dbo.UserDefinedFunction(...) f
    -- ORDER BY ... ?
END

对于此报告,我将在查询/存储过程之后使用(作为数据源):

SELECT s.Company, s.ProductID, s.PayeeID, SUM(Profit) AS SumOfProfit
FROM (
    SELECT DISTINCT f.Company, f.ProductID, f.PayeeID, f.GroupID, f.Profit
    FROM dbo.UserDefinedFunction(...) f
) s
GROUP BY s.Company, s.ProductID, s.PayeeID

3)当然,如果解决方案1和2不适用且if initial stored procedure don't include insert into another table,对于第二个报告,我们可以重用第一个存储过程(我不喜欢这种方法):

CREATE TABLE #Results (
    Company ...,
    ProductID INT,
    PayeeID INT,
    ...
)
INSERT #Results (...)
EXEC dbo.FirstStoredProcedure (...)
-- and then 
SELECT s.Company, s.ProductID, s.PayeeID, SUM(Profit) AS SumOfProfit
FROM (
    SELECT DISTINCT f.Company, f.ProductID, f.PayeeID, f.GroupID, f.Profit
    FROM #Results f
) s
GROUP BY s.Company, s.ProductID, s.PayeeID

答案 2 :(得分:0)

我在这里使用纯SSRS解决方案,但它非常难看且不必要的复杂。这个解决方案很有趣,所以我建议对大型数据集使用这种方法,我强烈建议使用T-SQL级解决方案。

根据您发布的数据集,我创建了以下Tablix:

enter image description here

我使用“列可见性”窗口隐藏了最后一列(详细信息列)。

enter image description here

使用自定义代码,您可以使用VB代码扩展SSRS功能的功能。转到Report菜单/ Report properties...切换到Code标签,然后将以下代码放入文字区域。

Public Function MySum(ByVal groups as Object(), ByVal values as Object()) As Integer
Dim found_groups As System.Collections.ArrayList=New System.Collections.ArrayList()
Dim n as Integer
Dim sum as Integer = 0
For n = 0 To groups.Length-1
    If not found_groups.Contains(groups(n)) Then
        found_groups.Add(groups(n))
        sum = sum + values(n)
    End If
Next
Return sum
End Function

在选定的单元格中(查看tablix截图)我使用了这个表达式:

=Code.MySum(Lookupset(
Fields!ProductID.Value &"-"&
Fields!PayeeID.Value &"-",
Fields!ProductID.Value &"-"&
Fields!PayeeID.Value &"-",
CStr(Fields!GroupID.Value),
"DataSet1"
),
Lookupset(
Fields!ProductID.Value &"-"&
Fields!PayeeID.Value &"-",
Fields!ProductID.Value &"-"&
Fields!PayeeID.Value &"-",
CStr(Fields!Profit.Value),
"DataSet1"
))

注意MySum()函数将两个数组作为参数并返回一个整数,即给定组中Profit值的总和。

预览这样的事情:

enter image description here

  

警告:此解决方案是基于提供的数据集构建的   你的问题,如果数据结构发生变化,它将无效。

如果有帮助,请告诉我。