динамическая группировка в SQL Server - PullRequest
2 голосов
/ 14 марта 2019

Я хочу сделать хранимую процедуру, как makeGroupBy(@a int,@b int,@c int). Входные данные - 0 или 1, чтобы решить, по каким столбцам группировать. Моя попытка пока что ниже:

-- exec makeGroupBy 0,1,0 
-- exec makeGroupBy 0,1,1 
create proc makeGroupBy(@product_id  int = 0,@city_id  int = 1,@date_key  
int = 0) as 
begin
declare @tbl as table(product_id  int, city_id  int, date_key  int, amount                  
float)

insert into @tbl
values(1,1,1,10),
(1,1,1,10),
(1,2,1,5),
(2,2,3,15),
(2,1,3,20),
(3,1,1,25)

select case isnull(@product_id,0) when 0 then 0 else product_id end 
    ,case isnull(@city_id,0) when 0 then 0 else city_id end
    ,case isnull(@date_key,0) when 0 then 0 else date_key end
    , sum(amount) amount from @tbl 
group by case isnull(@product_id,0) when 0 then 0 else product_id end 
    ,case isnull(@city_id,0) when 0 then 0 else city_id end
    ,case isnull(@date_key,0) when 0 then 0 else date_key end
end

Я не знаю, возможно ли это, но я хочу исключить ненужные столбцы (входные данные со значением 0) в наборе результатов.

1 Ответ

1 голос
/ 15 марта 2019

Предполагая, что ваша sql-server версия больше или равна 2008.

select 
    product_id
    ,city_id
    ,date_key
    ,sum(amount) as total_amount 
from @tbl
group by grouping sets (
            (product_id, city_id, date_key)
            , (product_id,city_id)
            , (product_id, date_key)
            , (city_id, date_key)
            , (product_id)
            , (city_id)
            , (date_key))
having concat(iif(grouping_id(product_id)=0,1,0),iif(grouping_id(city_id)=0,1,0),iif(grouping_id(date_key)=0,1,0)) = concat(@product_id, @city_id, @date_key) 
order by concat(iif(grouping_id(product_id)=0,1,0),iif(grouping_id(city_id)=0,1,0),iif(grouping_id(date_key)=0,1,0))

Кажется, что view, вероятно, подойдет лучше всего для этого случая

create view [view_name]
as 
select 
    product_id
    ,city_id
    ,date_key
    ,sum(amount) as amount 
    ,concat(iif(grouping_id(product_id)=0,1,0),iif(grouping_id(city_id)=0,1,0),iif(grouping_id(date_key)=0,1,0)) as grp_key
from @tbl
group by grouping sets (
        (product_id, city_id, date_key)
        , (product_id,city_id)
        , (product_id, date_key)
        , (city_id, date_key)
        , (product_id)
        , (city_id)
        , (date_key))
go

Затем вы можете запросить представление как

select 
    city_id
    ,date_key
    ,amount
from [view_name]
where grp_key = concat(0,1,1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...