sql >> データベース >  >> RDS >> PostgreSQL

複雑な「ギャップと島」の問題

    typeをどのように決定するかは不明です 各期間について。最小数を選択しました。

    この基本的なテーブル定義を想定すると:

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

    基本的に、ウィンドウ関数 をお勧めします。 同じ期間(島)のメンバーを識別するための2つのネストされたサブクエリ。次に集計:

    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;
    

    結果(サンプルデータに基づく):

      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
    

    同じ人の同じ日を異なるタイプで複数回入力でき、個別のみをカウントしたい場合 日数:count(DISTINCT eventdate) AS days

    関連、詳細な説明付き:

    ところで、eventdate - 6 データ型dateで機能します 、ただしtimestampではありません :




    1. サブクエリの結果に正規表現を使用するにはどうすればよいですか?

    2. MySQL高可用性フレームワークの説明–パートII:準同期レプリケーション

    3. ユーザーの質問を数える方法は?

    4. DOSバッチスクリプトでsqlplusエラーを検出しますか?