Вы можете сделать это без каких-либо объединений, используя UNPIVOT
, затем найти самые последние значения с помощью аналитической функции LAST_VALUE
и перегруппировать вокруг границ дат:
Oracle Setup :
CREATE TABLE table_name ( age, start_date, end_date, price, weighting, product_element_id ) AS
SELECT 1, DATE '2017-11-11', DATE '2017-12-21', 'BUY', 0.76, 1 FROM DUAL UNION ALL
SELECT 1, DATE '2017-11-11', DATE '2017-12-19', 'SELL', 16.27, 1 FROM DUAL UNION ALL
SELECT 1, DATE '2017-12-20', DATE '2018-01-02', 'SELL', 14.79, 1 FROM DUAL UNION ALL
SELECT 1, DATE '2017-12-22', DATE '2027-11-11', 'BUY', 0.71, 1 FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-18', DATE '2027-11-11', 'SELL', 24.75, 1 FROM DUAL;
Запрос :
SELECT age,
product_element_id,
MIN( DT ) AS start_date,
MAX( DT ) AS end_date,
MAX( start_buy_weighting ) AS start_buy_weighting,
MAX( start_sell_weighting ) AS start_sell_weighting
FROM (
SELECT p.*,
LAST_VALUE( CASE PRICE WHEN 'BUY' THEN weighting END )
IGNORE NULLS OVER ( PARTITION BY product_element_id ORDER BY dt ASC )
AS start_buy_weighting,
LAST_VALUE( CASE PRICE WHEN 'SELL' THEN weighting END )
IGNORE NULLS OVER ( PARTITION BY product_element_id ORDER BY dt ASC )
AS start_sell_weighting,
SUM( value ) OVER ( PARTITION BY product_element_id ORDER BY dt ASC )
AS grp
FROM table_name
UNPIVOT(
dt FOR value IN ( start_date As 1, end_date AS 0 )
) p
)
GROUP BY age, product_element_id, grp
Выход ;
AGE PRODUCT_ELEMENT_ID START_DATE END_DATE START_BUY_WEIGHTING START_SELL_WEIGHTING
--- ------------------ ---------- --------- ------------------- --------------------
1 1 11-NOV-17 19-DEC-17 .76 16.27
1 1 20-DEC-17 21-DEC-17 .76 14.79
1 1 22-DEC-17 02-JAN-18 .71 14.79
1 1 18-JAN-18 11-NOV-27 .71 24.75