2015-12-29 2 views
1

Я выполняю запрос, который получает несколько тысяч строк в качестве результата, а клиенту нужна строка, показывающая суммы сумм определенных числовых столбцов. Я достиг этого, используя группы по группам, но эта функция поддерживает до 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

Вы отображая тысячи строк, каждая строка имеет 45 столбцов в любом месте? –

+0

Да, это главная проблема. Я должен отображать каждый столбец. – Rambo3

+0

Используете ли вы цикл для отображения этих данных?Если это так, вычислите необходимые суммы внутри этого цикла и покажите их в конце. В стороне, попытка отобразить слишком много данных в веб-браузере часто заканчивается слезами, на всякий случай это то, что вы пытаетесь. –

ответ

1

Если вы пытаетесь сделать это в основном все данные плюс общая строка, рассмотрите следующий подход. Не группируйте по набору группировок, которые включают все неагрегированные столбцы, а не идентификатор группы по строке (существующий, который должен быть уникальным во всех строках данных или искусственный, созданный с помощью функции 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 

Сравните это со следующим запросом, который группирует данные по сингл colu млн. Также добавляется вспомогательная таблица @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 
+0

Удивительный, спасибо большое. – Rambo3

0

Учитывая только несколько тысяч строк, я бы использовал хранимую процедуру для получения результатов без итоговых итогов в таблице temp или переменной таблицы, а затем возвращал результаты в виде UNION ALL этой таблицы плюс общая сумма поверх его.

Смежные вопросы