Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Reduzieren Sie die tägliche Statustabelle, um nur Statusänderungen zu enthalten

Beachten Sie Folgendes:

Schema

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(user_id INT NOT NULL
,status CHAR(3) NOT NULL
,date DATE NOT NULL
,PRIMARY KEY(user_id,date)
);

INSERT INTO my_table VALUES
(1, 'GRE', '2018-09-02'),
(1, 'GRE', '2018-09-03'),
(1, 'PRO', '2018-09-04'),
(1, 'PRO', '2018-09-05'),
(1, 'PRO', '2018-09-06'),
(1, 'GRE', '2018-09-07'),
(1, 'GRE', '2018-09-08'),
(1, 'GRE', '2018-09-09'),
(1, 'GRE', '2018-09-10'),

(2, 'GRE', '2018-09-02'),
(2, 'GRE', '2018-09-03'),
(2, 'PRO', '2018-09-04'),
(2, 'PRO', '2018-09-05'),
(2, 'PRO', '2018-09-06'),
(2, 'GRE', '2018-09-07'),
(2, 'GRE', '2018-09-08'),
(2, 'GRE', '2018-09-09'),
(2, 'GRE', '2018-09-10');

Abfrage

WITH t AS (
  SELECT user_id
       , status
       , date
       , DENSE_RANK() OVER (PARTITION BY user_id ORDER BY date) 
       - DENSE_RANK() OVER (PARTITION BY user_id,status ORDER BY DATE) grp
    FROM my_table
    )
SELECT t.user_id
     , t.status
     , MIN(t.date) start
     , MAX(t.date) finish
  FROM t
 GROUP  
    BY user_id
     , status
     , grp
 ORDER  
    BY user_id
     , start;
     

+---------+--------+------------+------------+
| user_id | status | start      | finish     |
+---------+--------+------------+------------+
|       1 | GRE    | 2018-09-02 | 2018-09-03 |
|       1 | PRO    | 2018-09-04 | 2018-09-06 |
|       1 | GRE    | 2018-09-07 | 2018-09-10 |
|       2 | GRE    | 2018-09-02 | 2018-09-03 |
|       2 | PRO    | 2018-09-04 | 2018-09-06 |
|       2 | GRE    | 2018-09-07 | 2018-09-10 |
+---------+--------+------------+------------+