Sql 如何仅对结果集中每个组的第一行求和
好的,我会尽力解释我自己,但我有以下几点: 我有一个基本上是动态查询的数据源。查询本身显示3个字段,Name、Amount1、Amount2 现在,我可以有同名的行。这个想法是当名称与我保存的前一个名称不同时,将Amount1+Amount2相加。如果我在C#上这样做,可能是这样的:Sql 如何仅对结果集中每个组的第一行求和,sql,reporting-services,Sql,Reporting Services,好的,我会尽力解释我自己,但我有以下几点: 我有一个基本上是动态查询的数据源。查询本身显示3个字段,Name、Amount1、Amount2 现在,我可以有同名的行。这个想法是当名称与我保存的前一个名称不同时,将Amount1+Amount2相加。如果我在C#上这样做,可能是这样的: foreach (DataRow dr in repDset.Dataset.Rows) { total = (long)dr["Amount1"] + (long)dr["Amou
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();
}
}
=MAX(Fields!Total.Value, "TotalQueryDataset")
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;
我们的想法是抓住这一点,使用RS可以给我的方法生成Reporting Services表达式,例如:
IIF(Fields!Name.Value<>Previous(Fields!Name.Value),Fields!Amount1.Value + Fields!Amount2.Value,False)
IIF(Fields!Name.ValuePrevious(Fields!Name.Value),Fields!Amount1.Value+Fields!Amount2.Value,False)
类似的东西,但它存储了前一个的数量
也许创造另一个领域?经过计算的
如果需要,我可以进一步澄清和编辑
*编辑以进行视觉澄清:
例如,它是这样的:
此查询假定您正在使用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;
这使用分析窗口函数对每一行进行编号,partitionby子句告诉它为结果集中的每个不同的Name值重置编号。您确实需要一个可以排序结果的字段,否则这将不起作用。如果你真的想要一个随机的顺序,你可以通过NEWID()执行orderbynewid()
,但是这会给你一个不确定的结果
这种语法是SQL server特有的,但通常可以在其他数据库中实现
如果您希望像示例中所示那样显示输出,则可以使用两个查询并通过将其作为作用域传递给SSRS表达式中的聚合函数来引用另一个查询,如下所示:
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();
}
}
=MAX(Fields!Total.Value, "TotalQueryDataset")
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;
其中,数据集称为“TotalQueryDataset”
否则,您可以使用纯SQL实现如下输出:
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();
}
}
=MAX(Fields!Total.Value, "TotalQueryDataset")
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;
此查询假定您正在使用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;
这使用分析窗口函数对每一行进行编号,partitionby子句告诉它为结果集中的每个不同的Name值重置编号。您确实需要一个可以排序结果的字段,否则这将不起作用。如果你真的想要一个随机的顺序,你可以通过NEWID()执行orderbynewid()
,但是这会给你一个不确定的结果
这种语法是SQL server特有的,但通常可以在其他数据库中实现
如果您希望像示例中所示那样显示输出,则可以使用两个查询并通过将其作为作用域传递给SSRS表达式中的聚合函数来引用另一个查询,如下所示:
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();
}
}
=MAX(Fields!Total.Value, "TotalQueryDataset")
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;
其中,数据集称为“TotalQueryDataset”
否则,您可以使用纯SQL实现如下输出:
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();
}
}
=MAX(Fields!Total.Value, "TotalQueryDataset")
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;
你的问题没有道理。您的示例C#代码看起来像是在foreach中计算总数,然后执行if语句,然后退出。你的支架放错地方了吗?你的视觉说明中的数字也不正确。26来自哪里?你们的团体总数在哪里?我不明白你想实现什么。。。你的数据来源是什么?这听起来像是可以通过在SQL Server中对SUM()运算符进行分区来完成的,但这仅限于在使用SQL Server时。你能告诉我们你正在使用的查询吗?你好,迈克,我不能把这个查询放在这里,因为它是巨大的,就像我之前说的,它有点奇怪。C#代码只是一个示例,但其思想如下:以可视化示例为例。对于每个不同的名称,取第一个,求和Amount1+Amount2,这就是为什么26。堆栈:数量1(1)+数量2(0)=1。当遇到第一个“溢出”和时,忽略其他“堆栈”:Amount1(9)+Amount2(16),因此:1+25=26。我将在我的第一篇文章中编辑C#代码,以便更好地阐明它。我给出了一个解决方案,使用SQL来实现您想要的结果。如果你真的需要一个SSRS表达式解决方案,这是可能的,但它不会那么简单。你的问题没有意义。您的示例C#代码看起来像是在foreach中计算总数,然后执行if语句,然后退出。你的支架放错地方了吗?你的视觉说明中的数字也不正确。26来自哪里?你们的团体总数在哪里?我不明白你想实现什么。。。你的数据来源是什么?这听起来像是可以通过在SQL Server中对SUM()运算符进行分区来完成的,但这仅限于在使用SQL Server时。你能告诉我们你正在使用的查询吗?你好,迈克,我不能把这个查询放在这里,因为它是巨大的,就像我之前说的,它有点奇怪。C#代码只是一个示例,但其思想如下:以可视化示例为例。对于每个不同的名称,取第一个,求和Amount1+Amount2,这就是为什么26。堆栈:数量1(1)+数量2(0)=1。当遇到第一个“溢出”和时,忽略其他“堆栈”:Amount1(9)+Amount2(16),因此:1+25=26。我将在我的第一篇文章中编辑C#代码,以便更好地阐明它。我给出了一个解决方案,使用SQL来实现您想要的结果。如果你真的需要一个SSRS表达式解决方案,这可能是可能的,但不会那么简单。你好,迈克,谢谢你的回复。我一直在做一些调整,我的一个合作伙伴确实找到了一个很好的解决方案,让我们一起来看看:在您放入的代码中:
Dim Group as String=“0”函数TotalPDV(ByVal ThisGroup as String,ByVal value as Integer)如果Group=ThisGroup返回0 End作为整数如果Group=ThisGroup返回值End函数
,那么我们在数据集中创建一个计算字段,如下所示:=code.TotalPDV(Fields!.value,Fields!Amount1.value+Fields!Amount2.value)
,它可以工作。您好,迈克,谢谢