sql >> Databáze >  >> RDS >> PostgreSQL

Složitý problém „Mezery a ostrovy“.

Není jasné, jak určujete type za každé období. Zvolil jsem minimální počet.

Za předpokladu této základní definice tabulky:

CREATE TABLE tbl (person text, eventdate date, type int);

V zásadě doporučuji funkce oken ve dvou vnořených dílčích dotazech k identifikaci členů stejného období (ostrova). Poté agregujte:

SELECT person, period
     , min(eventdate) AS startdate
     , max(eventdate) AS enddate
     , count(*)       AS days
     , min(type)      AS type
FROM  (
   SELECT person, eventdate, type
        , count(gap) OVER (PARTITION BY person ORDER BY eventdate) AS period
   FROM  (
      SELECT person, eventdate, type
           , CASE WHEN lag(eventdate) OVER (PARTITION BY person ORDER BY eventdate)
                     > eventdate - 6  -- within 5 days
                  THEN NULL           -- same period
                  ELSE TRUE           -- next period
             END AS gap
      FROM   tbl
      ) sub
   ) sub
GROUP  BY person, period
ORDER  BY person, period;

Výsledek (na základě vašich příkladných dat):

  person  | period | startdate  |  enddate   | days | type
----------+--------+------------+------------+------+------
 <uuid-1> |      1 | 2016-05-14 | 2016-05-22 |    5 |  300
 <uuid-1> |      2 | 2016-05-30 | 2016-06-01 |    2 |  300
 <uuid-1> |      3 | 2016-06-21 | 2016-06-21 |    1 |  300
 <uuid-2> |      1 | 2016-05-22 | 2016-05-27 |    2 |  301
 <uuid-2> |      2 | 2016-06-15 | 2016-06-23 |    4 |  300
 <uuid-2> |      3 | 2016-06-30 | 2016-06-30 |    1 |  300
 <uuid-3> |      1 | 2016-05-14 | 2016-05-14 |    1 |  300
 <uuid-3> |      2 | 2016-06-30 | 2016-06-30 |    1 |  300
 <uuid-4> |      1 | 2016-06-16 | 2016-06-16 |    1 |  300
 <uuid-4> |      2 | 2016-06-30 | 2016-06-30 |    1 |  300
 <uuid-5> |      1 | 2016-06-20 | 2016-06-20 |    1 |  300

Pokud lze stejný den pro stejnou osobu zadat vícekrát s různými typy a chcete počítat pouze odlišné dnů, udělejte to:count(DISTINCT eventdate) AS days .

Související s podrobným vysvětlením:

BTW, eventdate - 6 funguje pro datový typ date , ale ne pro timestamp :




  1. Jak MapReduce funguje v Hadoopu

  2. Oracle PL/SQL získat IP server v4?

  3. Přetrvávat neprimitivní data v JPA

  4. Fragmentace tabulek Wordpress a MySQL