sql >> Database >  >> RDS >> PostgreSQL

Complex 'hiaten en eilanden'-probleem

Het is onduidelijk hoe u het type bepaalt voor elke periode. Ik heb het minimum aantal gekozen.

Uitgaande van deze basistabeldefinitie:

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

Kortom, ik stel voor vensterfuncties in twee geneste subquery's om leden van dezelfde periode (eiland) te identificeren. Verzamel dan:

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;

Resultaat (gebaseerd op uw voorbeeldgegevens):

  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

Als dezelfde dag voor dezelfde persoon meerdere keren kan worden ingevoerd met verschillende typen, en u wilt alleen verschillend tellen dagen, maak het:count(DISTINCT eventdate) AS days .

Gerelateerd, met gedetailleerde uitleg:

BTW, eventdate - 6 werkt voor gegevenstype date , maar niet voor timestamp :




  1. MySql:hoe maak je een subquery en tel je alle rijen waar id hetzelfde is in twee tabellen

  2. SQL DELETE voor beginners

  3. Entity-Framework -> MySql geeft 'Functie-evaluatie time-out'.

  4. Een back-up van SQL Server 2000 herstellen op SQL Server 2012