Динамическая группировка данных || Требуется SQL-запрос - PullRequest
0 голосов
/ 07 июля 2019
Year        Salary
2014        5000
2015        6500
2016        6800
2017        6900
2018        7000
2019        8000

Я хочу динамически группировать данные.Предположим, если я хочу группу из 2, тогда данные должны быть сгруппированы в 3 группы по 2 года в каждом Resultset:

Year          Salary
2014-2015     11500
2016-2017     13300
2018-2019     15000

Если я хочу группу из 3, то

Year.            Salary
2014-2016        18300
2017-2019        21900

Нет жесткого кодирования

Ответы [ 3 ]

2 голосов
/ 07 июля 2019

Вы можете сделать это, используя оконные функции и агрегирование.Предполагая, что вы хотите n лет в каждой группе:

select min(year), max(year), sum(salary)
from (select t.*, min(year) over () as min_year
      from t
     ) t
group by floor((year - min_year) / @n)
order by min(year);
0 голосов
/ 07 июля 2019

Опция 1 использует деление на количество лет и округление в меньшую сторону, чтобы разработать вызовы вложенных функций, которые возвращают желаемую группу YearGroup.Это может привести к путанице, но это возможно

Вариант 2 - наиболее гибким для любой платформы sql будет добавление таблицы (или представления) YearGroup с одним столбцом на нужную группу

Year | GroupOne  | GroupTwo | GroupThree
-----+-----------+----------+-----------
2019 | 2019.1    | 2018.2   | 2019.3
2018 | 2018.1    | 2018.2   | 2016.3
2017 | 2017.1    | 2016.2   | 2016.3
2016 | 2016.1    | 2016.2   | 2016.3
2015 | 2015.1    | 2014.2   | 2015.3
...

Десятичные числа необязательны, но хорошо сообщить людям количество лет в группе, хотя я предполагаю, что истинной третьей нормальной формой будет одна таблица в год, сгруппированная

Вариант 2 имеет дополнительное преимущество, которое может выбрать любой.из таблиц YearGroup, чтобы увидеть сопоставление из первых рук

Вы также можете добавить группы, у которых разные годы привязки, такие как группа два года с нечетным первым годом (слияние 2017 и 2018) по сравнению с первым годом (объединить 2018 с 2019)

0 голосов
/ 07 июля 2019

Например, вы можете создать несколько переменных, которые помогут вам в создании групп в таблице, т.е. @remainder помогает найти следующие группы в Year. В CTE я использовал sum as a window function плюс case, чтобы создать столбец для group by.

create table #years (Year int,        Salary int )
insert into #years values (2014        ,5000)
insert into #years values (2015        ,6500)
insert into #years values (2016        ,6800)
insert into #years values (2017        ,6900)
insert into #years values (2018        ,7000)
insert into #years values (2019        ,8000)

declare @minYear int = (select min(Year) from #years);
declare @RowsToGroup int = 2;
declare @remainder decimal(12,6) = (select @minYear % @RowsToGroup) ;

with YearsToGroup as (
select 
     *
    ,sum(case when Year % @RowsToGroup = @remainder then 1 else 0 end) over (order by Year asc) as grouping
from #years
)
select 
    cast(min(Year) as varchar(10)) + '-' + cast(max(Year) as varchar(10)) as years
    ,sum(salary) as salary
from YearsToGroup
group by grouping

Результаты для @RowsToGroup = 2:

years       salary
2014-2015   11500
2016-2017   13700
2018-2019   15000

Результаты для @RowsToGroup = 3:

years       salary
2014-2016   18300
2017-2019   21900
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...