Home > Back-end >  Grouping Binary Variable By ID and Min/Max Dates
Grouping Binary Variable By ID and Min/Max Dates

Time:09-16

Date Emp ID Dummy
01.01.2021 5 1
01.02.2021 5 1
01.03.2021 5 1
01.04.2021 5 1
01.05.2021 5 0
01.06.2021 5 1
01.07.2021 5 1
01.01.2021 8 1
01.02.2021 8 1
01.03.2021 8 1
01.04.2021 8 0
01.05.2021 8 0
01.06.2021 8 0
01.07.2021 8 1

Basically, I want to group the data by uninterrupted sequences of ones from the dummy column for each employee and state the associated max/min dates.

The desired output should look like this:

Emp ID Min Date Max Date Group Number
5 01.01.2021 01.04.2021 1
5 01.06.2021 01.07.2021 2
8 01.01.2021 01.03.2021 1
8 01.07.2021 01.07.2021 2

CodePudding user response:

From Oracle 12, this is the type of problem that MATCH_RECOGNIZE is intended to solve:

SELECT *
FROM   table_name
MATCH_RECOGNIZE (
  PARTITION BY Emp_ID
  ORDER     BY dt
  MEASURES
    FIRST(dt) AS min_date,
    LAST(dt)  AS max_date,
    MATCH_NUMBER() AS group_number
  PATTERN (one )
  DEFINE
    one AS dummy = 1
)

Which, for the sample data:

CREATE TABLE table_name ( dt, Emp_ID, Dummy ) AS
SELECT DATE '2021-01-01', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-02', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-03', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-04', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-05', 5, 0 FROM DUAL UNION ALL
SELECT DATE '2021-01-06', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-07', 5, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-01', 8, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-02', 8, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-03', 8, 1 FROM DUAL UNION ALL
SELECT DATE '2021-01-04', 8, 0 FROM DUAL UNION ALL
SELECT DATE '2021-01-05', 8, 0 FROM DUAL UNION ALL
SELECT DATE '2021-01-06', 8, 0 FROM DUAL UNION ALL
SELECT DATE '2021-01-07', 8, 1 FROM DUAL;

Outputs:

EMP_ID MIN_DATE MAX_DATE GROUP_NUMBER
5 2021-01-01 00:00:00 2021-01-04 00:00:00 1
5 2021-01-06 00:00:00 2021-01-07 00:00:00 2
8 2021-01-01 00:00:00 2021-01-03 00:00:00 1
8 2021-01-07 00:00:00 2021-01-07 00:00:00 2

db<>fiddle here

  • Related