Это даст желаемый результат, если вы также сгруппируете по году:
SQL Fiddle
Настройка схемы Oracle 11g R2 :
CREATE TABLE table_name (
customer_id,
customer_effective_date,
customer_term_date,
service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
Запрос 1 :
SELECT customer_id,
MIN( customer_effective_date ) AS customer_effective_date,
MAX( customer_term_date ) AS customer_term_date,
service
FROM table_name
GROUP BY
customer_id,
service,
TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
customer_effective_date
Результаты
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE | CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
| 1 | 2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z | Bike |
| 1 | 2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z | Car |
| 1 | 2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z | Bike |
Запрос 2 :
Это также объединит группы, если это проблема островков и разрывов, и сделает это без агрегации:
SELECT *
FROM (
SELECT customer_id,
LAST_VALUE( customer_effective_date )
IGNORE NULLS OVER (
PARTITION BY customer_id, service
ORDER BY COALESCE( customer_effective_date, customer_term_date )
) AS customer_effective_date,
customer_term_date,
service
FROM (
SELECT customer_id,
CASE
WHEN customer_effective_date
= LAG( customer_term_date, 1 ) OVER (
PARTITION BY customer_id, service
ORDER BY customer_effective_date
) + 1
THEN NULL
ELSE customer_effective_date
END AS customer_effective_date,
CASE
WHEN customer_term_date
= LEAD( customer_effective_date, 1 ) OVER (
PARTITION BY customer_id, service
ORDER BY customer_effective_date
) - 1
THEN NULL
ELSE customer_term_date
END AS customer_term_date,
service
FROM table_name
)
)
WHERE customer_term_date IS NOT NULL
ORDER BY customer_effective_date
Результаты
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE | CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
| 1 | 2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z | Bike |
| 1 | 2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z | Car |
| 1 | 2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z | Bike |