Есть ли SQL-запрос для подсчета количества людей в конкретном году, зная дату рождения и дату смерти каждого человека? - PullRequest
0 голосов
/ 06 июня 2019

У меня есть таблица с указанием имени, даты рождения и даты смерти людей (1900-2000).Мне нужно знать количество людей на каждый год в определенный период времени, например, в 1940 году население составляло 2,3 миллиарда, в 1941 году - 2,4 миллиарда, в 1942 году - 2,2 миллиарда и т. Д. До 1950 года.

Я работаю в SAS Enterprise Guide и, возможно, код будет немного отличаться от обычного SQL.По крайней мере, я хочу увидеть что-то вроде этого:

~ количество людей |год

2.300.000.000 | 1940 г. 2.400.000.000 | 1941 г. .....................

select
count(name),
from db
where bd<1jan1940 and dd>=1jan1940 and dd=<31dec1940
group by month

Ответы [ 2 ]

0 голосов
/ 10 июня 2019
data dob_data;
do i = 1 to 10000;
    num = ceil(rand('UNIFORM',0,10));   
    dob = intnx('day','01JAN1899'd,ceil(rand('UNIFORM',1,36865)));
    select (num);
        when (1)  dod = intnx('day',dob,ceil(rand('UNIFORM',1,36865)));
        otherwise dod = .;
    end;
    output;
end;
format dob dod date9.;
drop num;
run;


data calendar;
    do i=0 to 100;
        year = 1900+i;
        soy = intnx('year','01JAN1900'd,i,'s');
        eoy = intnx('year','01JAN1900'd,i,'e');
        output;
    end;
    format soy eoy date9.;
run;


proc sql;
    create table pop as
    select year,
    sum(case when DOB < soy and coalesce(DOD,'31DEC2200'd) ge soy then 1 else 0 end) as Alive_At_Start,
    sum(case when DOB between soy and eoy then 1 else 0 end) as Born_During,
    sum(case when coalesce(DOD,'31DEC2200'd) between soy and eoy then -1 else 0 end) as Passed,
    sum(case when DOB le eoy and coalesce(DOD,'31DEC2200'd) > eoy then 1 else 0 end) as Alive_At_End
    from dob_data t1, calendar t2
    group by year;
quit;
0 голосов
/ 06 июня 2019

Прежде всего, вы должны знать начальную популяцию в конце 1899 года. Скажем, это было 2 миллиарда.Затем добавьте число рождений минус число смертей за каждый год.(Вы должны получить доступ к таблице дважды, чтобы сделать это, один раз для рождений и один раз для смертей.) Используйте SUM OVER, чтобы получить промежуточный итог.

Я не уверен, какую СУБД вы на самом деле используете, ноэто довольно стандартный SQL:

select yr, 2000000000 + sum(births.cnt - deaths.cnt) over (order by yr)
from
(
  select extract(year from bd) as yr, count(*) as cnt 
  from db
  group by extract(year from bd)
) births
join
(
  select extract(year from dd) as yr, count(*) as cnt 
  from db
  group by extract(year from dd)
) deaths using (yr)
order by yr;
...