【问题标题】:How to sum only the first row for each group in a result set如何仅对结果集中每个组的第一行求和
【发布时间】:2015-09-15 16:08:48
【问题描述】:

好的,我会尽力解释自己,但我有以下几点:

我有一个基本上是动态查询的数据源。查询本身显示 3 个字段,Name、Amount1、Amount2。

现在,我可以拥有具有相同名称的行。这个想法是当名称与我保存的前一个不同时,计算 Amount1+Amount2 的总和。如果我在 C# 上执行此操作,可能是这样的:

    foreach (DataRow dr in repDset.Dataset.Rows)
    {
        total = (long)dr["Amount1"] + (long)dr["Amount2"];
        if (thisconditiontrue)
        {
            if (PreviousName == "" || PreviousName != dr["Name"].ToString())
            {
                TotalName = TotalName + total;
            }
            PreviousName = dr["Name"].ToString();
        }
    }

这个想法是抓住这个并使用 RS 可以给我的方法制作一个 Reporting Services 表达式,例如:

IIF(Fields!Name.Value<>Previous(Fields!Name.Value),Fields!Amount1.Value + Fields!Amount2.Value,False)

类似的东西,但它存储了前一个的数量。

也许创建另一个字段?计算出来的?

如果需要,我可以进一步澄清和编辑。

*为视觉澄清编辑: 例如,它是这样的:

【问题讨论】:

  • 你的问题没有意义。您的示例 C# 代码看起来像是在 foreach 中计算总数,然后执行 if 语句然后退出。你的括号不合适吗?您的视觉说明中​​的数字也不会相加。 26从哪里来?你的小组总数在哪里?我不明白你想要达到什么目的......你的数据源是什么?这听起来像是可以通过在 SQL Server 中对 SUM() 运算符进行分区来完成的,但前提是您使用的是 SQL Server。你能告诉我们你正在使用的查询吗?
  • 你好,迈克,我不能把查询放在这里,因为它很大,正如我之前所说的那样,它有点奇怪。 C# 代码只是一个示例,但想法如下:以可视化示例为例。对于每个不同的名称,抓住第一个,总和 Amount1+Amount2,这就是为什么 26。堆栈:Amount1 (1) + Amount2 (0) = 1。忽略其他“堆栈”,当您遇到第一个“溢出”总和时:Amount1 (9) + Amount2 (16) 所以:1 + 25 = 26。我将在我的初始帖子中编辑 C# 代码,以便更好地阐明它。
  • 我提供了一个使用 SQL 来实现您所追求的结果的解决方案。如果你真的需要一个 SSRS 表达式解决方案,它可能是可能的,但它不会那么简单。

标签: sql reporting-services


【解决方案1】:

此查询假设您正在使用 SQL Server。但是你需要一些东西来对查询结果进行排序,否则你怎么知道哪一行是第一行?

SELECT SUM(NameTotal) AS Total
FROM (
    SELECT Name, Amount1 + Amount2 AS NameTotal,
        ROW_NUMBER() OVER (ORDER BY OrderField PARTITION BY Name) AS rowNum
    FROM srcTable
) AS a
WHERE rowNum=1;

这使用分析窗口函数ROW_NUMBER() 对每一行进行编号,并且 PARTITION BY 子句告诉它为结果集中每个不同的 Name 值重置编号。您确实需要一个可以对结果进行排序的字段,否则这将不起作用。如果你真的只是想要一个随机顺序,你可以这样做 ORDER BY NEWID() 但这会给你一个不确定的结果。

这种语法是 SQL server 特有的,但通常可以在其他数据库中实现。

如果您希望像示例中所示那样显示输出,您可以使用两个查询并通过将其作为范围传递给 SSRS 表达式中的聚合函数来引用另一个查询,如下所示:

=MAX(Fields!Total.Value, "TotalQueryDataset")

您的数据集称为“TotalQueryDataset”。

否则你可以像这样使用纯 SQL 实现输出:

WITH nameTotals AS (
    SELECT Name, Amount1, Amount2,
        ROW_NUMBER() OVER (ORDER BY OrderField PARTITION BY Name) AS rowNum
    FROM srcTable
)
SELECT Name, Amount1, Amount2
FROM nameTotals

UNION ALL

SELECT 'Total', SUM(Amount1 + Amount2), NULL
FROM nameTotals
WHERE rowNum=1;

【讨论】:

  • 您好迈克,感谢您的回复。我一直在做一些调整,我的一个合作伙伴确实找到了一个很好的解决方案,让我们一起来看看: 在你输入的代码中:Dim Group as String = "0" Function TotalPDV(ByVal ThisGroup as String, ByVal value as Integer) As Integer If Group = ThisGroup Return 0 End If Group = ThisGroup Return value End Function 然后我们在 DataSet 中创建一个计算字段,如下所示:=Code.TotalPDV(Fields!&lt;MyGroup&gt;.Value, Fields!Amount1.Value + Fields!Amount2.Value) 它可以工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多