簡體   English   中英

獲取查詢結果總摘要行的最佳方法

[英]Best way to obtain total summary row of query result

我正在執行一個查詢,該查詢將獲得數千行結果,而客戶需要一行顯示某些數字列的總和。 我通過使用分組分組來實現此目的,但是此功能最多支持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), ())

我試圖將查詢一分為二,以使group by中的列數不達到可用的最大值。 如果我將每個查詢分開執行,則會得到所需的結果,但是如果我將它們合並,則會出錯(無法將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函數是否可用。

任何建議將被認真考慮。

提前致謝。

如果您要執行的操作基本上是所有數據加上總行,請考慮以下方法。 不要按包括所有未聚合列的分組集進行分組,而應按行ID分組(現有的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連接輔助表@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

僅給出幾千行,我將使用存儲過程將沒有總計的結果存儲到臨時表或表值變量中,然后將結果作為該表的UNION ALL加上頂部的總計返回它的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM