Как разделить один столбец на два столбца, чтобы он поддерживал данные в соответствии с другими столбцами, используя SQL - PullRequest
0 голосов
/ 26 сентября 2018

Here is the table

Я хочу, чтобы таблица выше выглядела так, как показано ниже: -

The table that I need

Я попробовал код ниже: -

SELECT * FROM 
( SELECT * FROM
(SELECT P.FACTOR_VALUE1 AS AGE,P.FACTOR_VALUE2 AS AREA, 
P.WEIGHTING AS BUY_FACTOR,0 AS SELL_FACTOR, 
P.START_DATE , P.END_DATE, L.PRODUCT_ELEMENT_ID 
FROM  PRICE_FACTOR_LOGIC L, PRICE_FACTOR P
WHERE L.MAPPING_ID=P.ELEMENT_LOGIC_ID AND  L.PRODUCT_ELEMENT_ID =1
AND L.FACTOR_ID =0
AND L.PRICE='BUY'

UNION

SELECT P.FACTOR_VALUE1 AS AGE,P.FACTOR_VALUE2 AS AREA, 
0 AS BUY_FACTOR,P.WEIGHTING AS SELL_FACTOR,
P.START_DATE, P.END_DATE, L.PRODUCT_ELEMENT_ID 
FROM  PRICE_FACTOR_LOGIC L, PRICE_FACTOR P
WHERE  L.MAPPING_ID=P.ELEMENT_LOGIC_ID  AND L.PRODUCT_ELEMENT_ID =1
AND L.FACTOR_ID =0
AND L.PRICE='SELL'  
) ORDER BY AGE,AREA, START_DATE
);

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Вы можете сделать это без каких-либо объединений, используя 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
0 голосов
/ 26 сентября 2018

Похоже, вам нужно присоединиться продает и покупает , используя надлежащие критерии даты, а затем назначить даты периода, используя три функции: least(), greatest(), lag().Приведенный ниже запрос дал мне желаемые результаты, пожалуйста, протестируйте его и при необходимости измените:

Демонстрация SQLFiddle

select greatest(d1, nvl(lag(d2) over (order by d1) + 1, d1)) start_date, 
       d2 end_date, price_buy, price_sell 
  from(select least(b.start_date, s.start_date) d1, least(b.end_date, s.end_date) d2,
              b.weighting price_buy, s.weighting price_sell, 
              b.start_date bsd, b.end_date bed, s.start_date ssd, s.end_date sed
         from (select * from t where price = 'BUY') b
         join (select * from t where price = 'SELL') s 
           on b.product_element_id = s.product_element_id 
          and s.end_date >= b.start_date and s.start_date <= b.end_date )
  order by start_date 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...