This is my table History:
productnr price changedate 1001 5 06.05.2020 1001 9 01.10.2021 1001 10 08.10.2021 1002 6 01.04.2021 1002 7 14.05.2021 1002 14 07.10.2021
I need to have every product which its price change last week AND the difference between last price and new price is more than 15 percent.
The desired result:
productnr newprice oldprice last_changedate secondlast_changedate 1002 14 7 07.10.2021 14.05.2021
With this SQL query I have all products which their price changed last week :
Select * from history where TO_CHAR(changedate, 'iw') = TO_CHAR(next_day(trunc(sysdate+2), 'MONDAY') - 14, 'iw') and changedate > sysdate - 14
But I have no idea how can reach the desired result.
Advertisement
Answer
You can use the analytic functions to find the previous values:
If you want to compare the latest productnr
to the previous:
SELECT * FROM ( SELECT h.*, LEAD(price ) OVER (PARTITION BY productnr ORDER BY changedate DESC) AS oldprice, LEAD(changedate) OVER (PARTITION BY productnr ORDER BY changedate DESC) AS oldchangedate, ROW_NUMBER() OVER (PARTITION BY productnr ORDER BY changedate DESC) AS rn FROM history h WHERE changedate > TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY ) WHERE (price < oldprice * (1 - 0.15) OR price > oldprice * (1 + 0.15)) AND rn = 1;
or, if you want to compare the first price
per productnr
this week to the last price
last week:
SELECT * FROM ( SELECT h.*, LEAD(price ) OVER (PARTITION BY productnr ORDER BY changedate DESC) AS oldprice, LEAD(changedate) OVER (PARTITION BY productnr ORDER BY changedate DESC) AS oldchangedate FROM history h WHERE changedate >= TRUNC(SYSDATE, 'IW') - INTERVAL '7' DAY AND changedate < TRUNC(SYSDATE, 'IW') + INTERVAL '7' DAY ) WHERE (price < oldprice * (1 - 0.15) OR price > oldprice * (1 + 0.15)) AND changedate >= TRUNC(SYSDATE, 'IW') AND oldchangedate < TRUNC(SYSDATE, 'IW');