Sql создает запрос, который делит строку на несколько групп - PullRequest
0 голосов
/ 10 мая 2018

Я довольно новичок в SQL, и у меня небольшая проблема.поэтому у меня есть эта таблица «main.person», в которой есть значения «Balance» и «birthYear».Теперь я хочу сгенерировать статистику, которая показывает общий баланс 3 разных групп рождения.так, например, от минимума рождения года (самый старый) до 1/3 диапазона.затем от 1/3 диапазона до 2/3.затем от 2/3 до самого младшего (максимальное значение)

Я пытался сделать это с Ntile, но это не работает, потому что он не группирует диапазон в 3 группыдовольно хорошо, поскольку, например, 1958 год - это та же группа, которая равна 1, но также и группа 2. Любая помощь будет принята с благодарностью.Спасибо.

это мой код:

create or alter procedure main.generateStatistics
as
begin
declare @bracket table(
balance numeric(9,2) not null,
bracket nvarchar(20))

insert into @bracket([balance],[bracket])
SELECT balance, NTILE(3) OVER(ORDER BY birthYear) from main.person p) as z



set @group1 = (select sum(balance) from @bracket
where bracket = 1)


set @group2 = (select sum(balance) from @bracket
where bracket = 2)

set @group3 = (select sum(balance) from @bracket
where bracket = 3)

insert into main.[stats](dateCollected,totalPeople,bracket1,bracket2,bracket3)
values(SYSDATETIMEOFFSET(),(select count(*) from main.person), @group1, @group2,@group3)
end;

пример того, как я хочу, чтобы моя группировка была

set @group1=(
select sum(balance) from main.person p
where birthYear <= 1959)

set @group2=(
select sum(balance) from main.person p
where birthYear >= 1960 and birthYear <= 1979)

set @group3=(
select sum(balance) from main.person p
where birthYear >= 1980)

[image

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

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

with bucket(grp, birthyear) as (
  select ntile(3) over (order by birthyear) grp
       , birthyear
    from (select distinct birthyear from person) x
)
select grp
     , min(p.birthyear) minyear
     , max(p.birthyear) maxyear
     , sum(balance) bal
  from person p
  join bucket b
    on b.birthyear = p.birthyear
 group by grp

Каждая группа будет содержать почти одинаковое количество лет рождения (± 1)без разбивки по годам.

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

declare @bucket (grp int, birthyear int);

insert into @bucket(grp, birthyear) 
  select ntile(3) over (order by birthyear) grp
       , birthyear
    from (select distinct birthyear from person) x;

select @group1 = sum(balance) bal
  from person p
  join bucket b
    on b.birthyear = p.birthyear
 where grp = 1;

select @group2 = sum(balance) bal
  from person p
  join bucket b
    on b.birthyear = p.birthyear
 where grp = 2;

select @group3 = sum(balance) bal
  from person p
  join bucket b
    on b.birthyear = p.birthyear
 where grp = 3;

Затем вы можете закончить вставкойзаявление.

0 голосов
/ 10 мая 2018

Хммм, вы можете использовать percentile_cont() или percentile_disc():

select (case when birthyear <= percentile_cont(0.333) within group (order by birthyear) over ()
             then 1
             when birthyear <= percentile_cont(0.667) within group (order by birthyear) over ()
             then 2
             else 3
        end)

Обратите внимание, что ваши контейнеры могут значительно различаться по размеру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...