Это то, что известно как проблема "подгонки".В вашем случае вы пытаетесь вписать свои данные в группы, каждая из которых может содержать данные за 16 дней.
Существует несколько хорошо известных способов использования SQL для решения проблем подбора бинов.MATCH RECOGNIZE
так же хорош, как и любой из них:
with test_data (IDE, "DATE") AS (
SELECT 'AA1111', TO_DATE('23-05-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('25-05-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('25-05-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('13-09-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('02-11-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('23-11-2016','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('06-02-2017','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('06-06-2017','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('01-09-2017','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('12-10-2017','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('17-04-2018','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('25-05-2018','DD-MM-YYYY') FROM DUAL UNION ALL
SELECT 'AA1111', TO_DATE('05-06-2018','DD-MM-YYYY') FROM DUAL )
SELECT ide, "DATE", mno as "GROUP"
FROM test_data
match_recognize (
partition by ide
order by "DATE"
measures
match_number() as mno,
"DATE" - FIRST(GRP."DATE") as dif
all rows per match
pattern ( grp* )
define
grp AS "DATE" - FIRST("DATE") < 16
);
Результаты
+--------+-----------+-------+
| IDE | DATE | GROUP |
+--------+-----------+-------+
| AA1111 | 23-MAY-16 | 1 |
| AA1111 | 25-MAY-16 | 1 |
| AA1111 | 25-MAY-16 | 1 |
| AA1111 | 13-SEP-16 | 2 |
| AA1111 | 02-NOV-16 | 3 |
| AA1111 | 23-NOV-16 | 4 |
| AA1111 | 06-FEB-17 | 5 |
| AA1111 | 06-JUN-17 | 6 |
| AA1111 | 01-SEP-17 | 7 |
| AA1111 | 12-OCT-17 | 8 |
| AA1111 | 17-APR-18 | 9 |
| AA1111 | 25-MAY-18 | 10 |
| AA1111 | 05-JUN-18 | 10 |
+--------+-----------+-------+
Обновление для 11g пользователей с использованием MODEL
предложение
Этот запрос должен работать на 11g, чтобы решить вашу проблему с бином.Те же результаты, что и выше, просто другой подход.
with
-- First, sort the input data because we need to be able to refer
-- to the prior row and `lag` doesn't really work in `MODEL`, afaik.
sorted_inputs ( ide, sort_order, "DATE", first_date_in_group, grp, diff) as
( SELECT ide,
row_number() over ( partition by ide order by "DATE" ) sort_order,
"DATE",
-- These columns are place holders for the MODEL clause to update
CAST(NULL AS DATE) first_date_in_group,
0 grp,
0 diff
FROM test_data )
SELECT ide, "DATE", grp "GROUP"
from sorted_inputs
model
partition by (ide)
dimension by (sort_order)
measures ( "DATE", grp, first_date_in_group, diff )
rules update automatic order
( grp[1] = 1,
first_date_in_group[1] = "DATE"[1],
diff[ANY] = "DATE"[CV()] - first_date_in_group[CV()-1],
grp[sort_order>1] = grp[cv()-1] + CASE WHEN diff[CV()] > 16 THEN 1 ELSE 0 END,
first_date_in_group[sort_order>1] = CASE WHEN diff[CV()] > 16 THEN "DATE"[CV()] ELSE first_date_in_group[CV()-1] END
)