lebende Personen zwischen 2 Datum-Eingaben

Hi,

Meine Tabelle:
id;geburt; gestorben; name

1;2016-11-29;2017-02-20;Lukas
2;2017-01-01; ;Lutz
3;2017-01-01;2017-01-05;Peter
4;2017-01-06;2017-02-20;Stefan
5;2017-02-24; ;Lisa
6;2017-05-30; ;Tobias

Ich möchte nun wissen, wie viele an den einzelnen Tagen zwischen 2017-01-01 und 2017-02-24 gelebt haben. Das soll mir gruppiert nach Ereignisdatum ausgegeben werden:

2017-01-01: 3
2017-01-05: 2
2017-01-06: 3
2017-02-20: 1
2017-02-24: 2

Ist das so überhaupt möglich?

Ein Teil der Where-Klausel muss aber so aussehen:

where geburt < '2017-02-24' and (gestorben is null or gestorben > '2017-01-02')

oder?

Ich hoffe hier kann mir jemand weiter helfen :slight_smile:

test=*# select * from jayjay ;
   geburt   | gestorben  |  name  
------------+------------+--------
 2016-11-29 | 2017-02-20 | Lukas
 2017-01-01 |            | Lutz
 2017-01-01 | 2017-01-05 | Peter
 2017-01-06 | 2017-02-20 | Stefan
 2017-02-24 |            | Lisa
 2017-05-30 |            | Tobias
(6 Zeilen)

test=*# select d, count(1) from (select d::date, j.name from generate_series('2017-01-01'::date, '2017-02-24'::date, '1day') d left join jayjay j on daterange(j.geburt,j.gestorben) @> d::date) foo group by d order by d;
     d      | count 
------------+-------
 2017-01-01 |     3
 2017-01-02 |     3
 2017-01-03 |     3
 2017-01-04 |     3
 2017-01-05 |     2
 2017-01-06 |     3
 2017-01-07 |     3
 2017-01-08 |     3
 2017-01-09 |     3
 2017-01-10 |     3
 2017-01-11 |     3
 2017-01-12 |     3
 2017-01-13 |     3
 2017-01-14 |     3
 2017-01-15 |     3
 2017-01-16 |     3
 2017-01-17 |     3
 2017-01-18 |     3
 2017-01-19 |     3
 2017-01-20 |     3
 2017-01-21 |     3
 2017-01-22 |     3
 2017-01-23 |     3
 2017-01-24 |     3
 2017-01-25 |     3
 2017-01-26 |     3
 2017-01-27 |     3
 2017-01-28 |     3
 2017-01-29 |     3
 2017-01-30 |     3
 2017-01-31 |     3
 2017-02-01 |     3
 2017-02-02 |     3
 2017-02-03 |     3
 2017-02-04 |     3
 2017-02-05 |     3
 2017-02-06 |     3
 2017-02-07 |     3
 2017-02-08 |     3
 2017-02-09 |     3
 2017-02-10 |     3
 2017-02-11 |     3
 2017-02-12 |     3
 2017-02-13 |     3
 2017-02-14 |     3
 2017-02-15 |     3
 2017-02-16 |     3
 2017-02-17 |     3
 2017-02-18 |     3
 2017-02-19 |     3
 2017-02-20 |     1
 2017-02-21 |     1
 2017-02-22 |     1
 2017-02-23 |     1
 2017-02-24 |     2
(55 Zeilen)

test=*#

Bei mir heißt die Tabelle Ereignis.

Ergebnismenge nur mit den Ereignistagen:

with stichtag as (
    select distinct geburt as stichtag
        from ereignis
        where geburt < '2017-02-24'
    union
    select distinct gestorben as stichtag
        from ereignis
        where gestorben > '2017-01-02'
)
select s.stichtag
        , (select count(*) 
            from ereignis
                where s.stichtag between geburt and coalesce( gestorben, '2999-12-31')) as cnt
    from stichtag s
    order by s.stichtag;



  stichtag  | cnt
------------+-----
 2016-11-29 |   1
 2017-01-01 |   3
 2017-01-05 |   3
 2017-01-06 |   3
 2017-02-20 |   3
(5 Zeilen)

Allerdings komme ich auf 3 Treffer bspw. am 20.02.2017:

frastr@test.[local]# select * from ereignis where '2017-02-20' between geburt and coalesce( gestorben, '2999-12-31');
 id |   geburt   | gestorben  |  name
----+------------+------------+--------
  1 | 2016-11-29 | 2017-02-20 | Lukas
  2 | 2017-01-01 |            | Lutz
  4 | 2017-01-06 | 2017-02-20 | Stefan
(3 Zeilen)

Was für mich aber korrekt aussieht. Oder zählt der Todestag nicht?

Danke für eure Bemühungen und die raschen Lösungsvorschläge!

Ich habe die Abfrage von frastr übernommen und noch um eine where erweitert:

with stichtag as (
    select distinct geburt as stichtag
        from person
        where geburt <= '2017-02-24'
    union
    select distinct gestorben as stichtag
        from person
        where gestorben >= '2017-01-02'
)
select s.stichtag
        , (select count(*) 
            from person
                where s.stichtag between geburt and coalesce( gestorben, '2999-12-31')) as cnt
    from stichtag s
    where s.stichtag >='2017-01-02'
    and s.stichtag <='2017-02-24'
    order by s.stichtag;

jetzt werden auch nur die Daten zwischen dem gewählten Zeitraum ausgegeben und keine früheren.

Danke nochmal! :slight_smile: