PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Vấn đề phức tạp về 'Khoảng cách và Quần đảo'

Không rõ bạn xác định loại type cho mỗi thời kỳ. Tôi đã chọn số lượng tối thiểu.

Giả sử định nghĩa bảng cơ bản này:

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

Về cơ bản, tôi đề xuất chức năng cửa sổ trong hai truy vấn con lồng nhau để xác định các thành viên của cùng một chu kỳ (đảo). Sau đó tổng hợp lại:

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;

Kết quả (dựa trên dữ liệu mẫu của bạn):

  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

Nếu cùng một ngày cho cùng một người, bạn có thể nhập nhiều lần với các loại khác nhau và bạn chỉ muốn đếm khác biệt ngày, hãy làm cho nó:count(DISTINCT eventdate) AS days .

Có liên quan, với giải thích chi tiết:

BTW, eventdate - 6 hoạt động cho kiểu dữ liệu date , nhưng không dành cho timestamp :




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bash Script để cài đặt PostgreSQL - Không hoạt động

  2. Tôi đang thực hiện n không. quy trình trong đó n có thể nằm trong khoảng từ 5 - 50. Mỗi quy trình thực hiện nhiều thao tác dml trên postgres

  3. Các khái niệm về Tính khả dụng cao của Oracle trong PostgreSQL

  4. Chạy tệp .sql PostgreSQL bằng cách sử dụng các đối số dòng lệnh

  5. Tránh lỗi PG ::InvalidTextRepresentation khi sử dụng UUID Postgres trong Rails