我正在执行一个查询,结果会产生几千行,而客户需要一行显示某些数字列的总和。我通过使用group by grouping来实现这一点,但是这个函数最多支持32个不在聚合函数中的列。我的问题是我有近45列我必须返回,因为集合函数,我只剩下10个列。
原始查询是这样的:
select
o.Name,
ci.Id,
ci.OriginId,
ci.Varchar1,
ci.Varchar2,
ci.Varchar3,
ci.Varchar4,
ci.Varchar5,
ci.Varchar6,
ci.Varchar7,
ci.Varchar8,
ci.Varchar9,
ci.Varchar10,
ci.Varchar11,
ci.Varchar12,
ci.Varchar13,
ci.Varchar14,
ci.Varchar15,
ci.Varchar16,
ci.Varchar17,
ci.Varchar18,
ci.Varchar19,
ci.Varchar20,
sum(ci.Decimal1) as Decimal1,
sum(ci.Decimal1) as Decimal2,
sum(ci.Decimal1) as Decimal3,
sum(ci.Decimal1) as Decimal4,
sum(ci.Decimal1) as Decimal5,
sum(ci.Decimal1) as Decimal6,
sum(ci.Decimal1) as Decimal7,
sum(ci.Decimal1) as Decimal8,
sum(ci.Decimal1) as Decimal9,
sum(ci.Decimal1) as Decimal10,
ci.Date1,
ci.Date2,
ci.Date3,
ci.Date4,
ci.Date5,
ci.Date6,
ci.Date7,
ci.Date8,
ci.Date9,
ci.Date10
from
Items ci
inner join Origins o
on ci.OriginId = o.Id
group by grouping sets((
o.Name,
ci.Id,
ci.OriginId,
ci.Varchar1,
ci.Varchar2,
ci.Varchar3,
ci.Varchar4,
ci.Varchar5,
ci.Varchar6,
ci.Varchar7,
ci.Varchar8,
ci.Varchar9,
ci.Varchar10,
ci.Varchar11,
ci.Varchar12,
ci.Varchar13,
ci.Varchar14,
ci.Varchar15,
ci.Varchar16,
ci.Varchar17,
ci.Varchar18,
ci.Varchar19,
ci.Varchar20,
ci.Date1,
ci.Date2,
ci.Date3,
ci.Date4,
ci.Date5,
ci.Date6,
ci.Date7,
ci.Date8,
ci.Date9,
ci.Date10), ())
我尝试将查询拆分为两个,以便组中的列数未达到可用的最大值。如果我执行每个查询分开,我得到所需的结果,但如果我联合它们我有一个错误(不能将nvarchar转换为数字)。
结果是这样的:
select
o.name
ci.Id,
ci.OriginId,
sum(ci.Decimal1) as Decimal1,
sum(ci.Decimal1) as Decimal2,
sum(ci.Decimal1) as Decimal3,
sum(ci.Decimal1) as Decimal4,
sum(ci.Decimal1) as Decimal5,
sum(ci.Decimal1) as Decimal6,
sum(ci.Decimal1) as Decimal7,
sum(ci.Decimal1) as Decimal8,
sum(ci.Decimal1) as Decimal9,
sum(ci.Decimal1) as Decimal10,
ci.Date1,
ci.Date2,
ci.Date3,
ci.Date4,
ci.Date5,
ci.Date6,
ci.Date7,
ci.Date8,
ci.Date9,
ci.Date10
from
Items ci
inner join Origins o
on ci.OriginId = o.Id
group by grouping sets((
o.Name,
ci.Id,
ci.OriginId,
ci.Date1,
ci.Date2,
ci.Date3,
ci.Date4,
ci.Date5,
ci.Date6,
ci.Date7,
ci.Date8,
ci.Date9,
ci.Date10), ())
union
select
o.Name,
ci.Id,
ci.OriginId,
ci.Varchar1,
ci.Varchar2,
ci.Varchar3,
ci.Varchar4,
ci.Varchar5,
ci.Varchar6,
ci.Varchar7,
ci.Varchar8,
ci.Varchar9,
ci.Varchar10,
ci.Varchar11,
ci.Varchar12,
ci.Varchar13,
ci.Varchar14,
ci.Varchar15,
ci.Varchar16,
ci.Varchar17,
ci.Varchar18,
ci.Varchar19,
ci.Varchar20
from
Items ci
inner join Origins o
on ci.OriginId = o.Id
group by grouping sets((
o.name,
ci.Id,
ci.OriginId,
ci.Varchar1,
ci.Varchar2,
ci.Varchar3,
ci.Varchar4,
ci.Varchar5,
ci.Varchar6,
ci.Varchar7,
ci.Varchar8,
ci.Varchar9,
ci.Varchar10,
ci.Varchar11,
ci.Varchar12,
ci.Varchar13,
ci.Varchar14,
ci.Varchar15,
ci.Varchar16,
ci.Varchar17,
ci.Varchar18,
ci.Varchar19,
ci.Varchar20), ())
另一种方法(如果可能的话)是通过在SQL中对集合进行分组并使用C#生成一行来删除组,因为查询的结果是由IEnumerable接收的,但我不知道是否有SUM函数是可用的。
任何建议都将受到赞赏。
提前致谢。
答案 0 :(得分:1)
如果您要执行的操作基本上是所有数据加上总行数,请考虑以下方法。不要按包括所有非聚合列的分组进行分组,而是按行ID分组(现有的一个,在所有数据行中应该是唯一的,或者是用row_number()
函数创建的人工)。还要考虑在计算总数后加入辅助表。
示例如下。
设置样本数据:
declare @origs table (id int, name varchar(20));
insert into @origs values (1, 'orig1'), (2, 'orig2');
declare @items table (
id int, orig_id int,
column1 varchar(20), column2 varchar(20),
value1 float, value2 float);
insert into @items values
(1, 1, 'c1.1', 'c2.1', 100, 10)
,(2, 1, 'c1.2', 'c2.2', 200, 20)
,(3, 2, 'c1.3', 'c2.3', 300, 30);
以下查询以您尝试执行此操作的方式返回所有数据和总行数:
select i.id, o.name as orig, i.column1, i.column2, sum(i.value1) val1, sum(i.value2) val2
from @items i
join @origs o on o.id = i.orig_id
group by grouping sets ((i.id, o.name, i.column1, i.column2), ());
输出结果为:
id orig column1 column2 val1 val2
----- ----- -------- -------- ----- -----
1 orig1 c1.1 c2.1 100 10
2 orig1 c1.2 c2.2 200 20
3 orig2 c1.3 c2.3 300 30
NULL NULL NULL NULL 600 60
将其与下一个查询进行比较,该查询按单个列对数据进行分组。 数据分组后,辅助表@origs
也会加入。
;with items as (
select
case grouping(id) when 0 then max(id) else NULL end id,
case grouping(id) when 0 then max(orig_id) else NULL end orig_id,
case grouping(id) when 0 then max(column1) else NULL end column1,
case grouping(id) when 0 then max(column2) else NULL end column2,
val1 = sum(value1),
val2 = sum(value2)
from @items
group by rollup (id)
)
select i.id, o.name as orig, i.column1, i.column2, i.val1, i.val2
from items i
left join @origs o on o.id = i.orig_id;
输出相同:
id orig column1 column2 val1 val2
----- ----- -------- -------- ----- -----
1 orig1 c1.1 c2.1 100 10
2 orig1 c1.2 c2.2 200 20
3 orig2 c1.3 c2.3 300 30
NULL NULL NULL NULL 600 60
答案 1 :(得分:0)
只给出几千行,我将使用存储过程将没有总计的结果放入临时表或表值变量中,然后将结果作为该表的UNION ALL
加上超过它的顶部。