![](/img/trans.png)
[英]In SQL how to compare values in two rows in the same table and find the highest value and then select its the entire row
[英]How to compare rows in a table and keep the highest values in the row in Oracle
我正在尋找一個查詢,它將當前行值與前一行值進行比較,如果當前和前一個之間的差異百分比小於 10%,則保留前一個值。 我確信使用 oracle 滯后函數可以實現這一點,但我無法找到確切的解決方案。 我試過下面的查詢,但它沒有保留未來行的先前值。 對此的任何幫助將不勝感激。
我使用下面的查詢來獲取結果,但它沒有解決我的問題。
select /*+ parallel(64) */ a, b, c, datevalue, pricevalue,
lag(pricevalue,1,0) over (partition by a, b, c order by a, b, c, datevalue) as prev_pricevalue,
(pricevalue - lag(pricevalue,1,0) over (partition by a, b, c order by a, b, c, datevalue))/pricevalue as diff,
case
when (pricevalue - lag(pricevalue,1,0) over (partition by a, b, c order by a, b, c, datevalue))/pricevalue
< 0.1 then lag(pricevalue,1,0) over (partition by a, b, c order by a, b, c, datevalue)
else pricevalue
end new_pricevalue
from table1
where datevalue between '18-MAY-2019' and '31-MAY-2019';
我有如下數據。 列名稱為 A、B、C、DATE 和 VALUE
A B C DATE VALUE
16587EA_1005 RETAIL 7207 18/05/2019 7.04
16587EA_1005 RETAIL 7207 19/05/2019 7.04
16587EA_1005 RETAIL 7207 20/05/2019 7.04
16587EA_1005 RETAIL 7207 21/05/2019 7.04
16587EA_1005 RETAIL 7207 22/05/2019 7.04
16587EA_1005 RETAIL 7207 23/05/2019 7
16587EA_1005 RETAIL 7207 24/05/2019 7
16587EA_1005 RETAIL 7207 25/05/2019 7
16587EA_1005 RETAIL 7207 26/05/2019 7
16587EA_1005 RETAIL 7207 27/05/2019 7
16587EA_1005 RETAIL 7207 28/05/2019 7
16587EA_1005 RETAIL 7207 29/05/2019 8
16587EA_1005 RETAIL 7207 30/05/2019 8
16587EA_1005 RETAIL 7207 31/05/2019 8
16587EA_1005 RETAIL 7207 01/06/2019 8.05
16587EA_1005 RETAIL 7207 02/06/2019 8.05
16587EA_1005 RETAIL 7207 03/06/2019 8.05
而且,我想要如下輸出。
A B C DATE VALUE
16587EA_1005 RETAIL 7207 18/05/2019 7.04
16587EA_1005 RETAIL 7207 19/05/2019 7.04
16587EA_1005 RETAIL 7207 20/05/2019 7.04
16587EA_1005 RETAIL 7207 21/05/2019 7.04
16587EA_1005 RETAIL 7207 22/05/2019 7.04
16587EA_1005 RETAIL 7207 23/05/2019 7.04
16587EA_1005 RETAIL 7207 24/05/2019 7.04
16587EA_1005 RETAIL 7207 25/05/2019 7.04
16587EA_1005 RETAIL 7207 26/05/2019 7.04
16587EA_1005 RETAIL 7207 27/05/2019 7.04
16587EA_1005 RETAIL 7207 28/05/2019 7.04
16587EA_1005 RETAIL 7207 29/05/2019 8
16587EA_1005 RETAIL 7207 30/05/2019 8
16587EA_1005 RETAIL 7207 31/05/2019 8
16587EA_1005 RETAIL 7207 01/06/2019 8
16587EA_1005 RETAIL 7207 02/06/2019 8
16587EA_1005 RETAIL 7207 03/06/2019 8
最好的問候 MMR
不完全是一種簡潔的方法,但遞歸 CTE 可以做到這一點。
WITH CTE AS
(
-- adding a rank and rownum
SELECT t.*
, DENSE_RANK() OVER (ORDER BY a, b, c) AS rnk
, ROW_NUMBER() OVER (PARTITION BY a, b, c ORDER BY datevalue) rn
FROM table1 t
),
RCTE (rnk, rn, a, b, c, datevalue, pricevalue) AS
(
-- seeding the recursion
SELECT rnk, rn, a, b, c, datevalue, pricevalue
FROM CTE
WHERE rn = 1
UNION ALL
-- loop through the records for each rank
SELECT c.rnk, c.rn, c.a, c.b, c.c, c.datevalue,
CASE
WHEN ABS(r.pricevalue - c.pricevalue) / c.pricevalue < 0.1
THEN r.pricevalue
ELSE c.pricevalue
END
FROM RCTE r
JOIN CTE c
ON c.rnk = r.rnk
AND c.rn = r.rn + 1
)
SELECT *
FROM RCTE
ORDER BY rnk, rn;
返回:
\n RNK | 注冊護士 | 一個 | 乙 | C | 日期值 | 價格值\n --: | -: | :- | :- | :- | :-------- | ---------:\n 1 | 1 | | 乙 | | | 2019 年 5 月 18 日 | 7.04\n 1 | 2 | | 乙 | | | 2019 年 5 月 19 日 | 7.04\n 1 | 3 | | 乙 | | | 19 年 5 月 20 日 | 7.04\n 1 | 4 | | 乙 | | | 2019 年 5 月 21 日 | 7.04\n 1 | 5 | | 乙 | | | 19 年 5 月 22 日 | 7.04\n 1 | 6 | | 乙 | | | 19 年 5 月 23 日 | 7.04\n 1 | 7 | | 乙 | | | 19 年 5 月 24 日 | 7.04\n 1 | 8 | | 乙 | | | 19 年 5 月 25 日 | 7.04\n 1 | 9 | | 乙 | | | 19 年 5 月 26 日 | 7.04\n 1 | 10 | | 乙 | | | 19 年 5 月 27 日 | 7.04\n 1 | 11 | | 乙 | | | 19 年 5 月 28 日 | 7.04\n 1 | 12 | | 乙 | | | 19 年 5 月 29 日 | 8\n 1 | 13 | | 乙 | | | 19 年 5 月 30 日 | 8\n 1 | 14 | | 乙 | | | 2019 年 5 月 31 日 | 8\n 1 | 15 | | 乙 | | | 01-JUN-19 | 8\n 1 | 16 | | 乙 | | | 02-JUN-19 | 8\n
對db<>fiddle 的測試在這里
我的嘗試 :) 您可以檢測變化是否大於 10% 並在那里使用新值,在其他情況下留空。 然后使用帶有ignore nulls
子句的lag
:
select a, b, c, dv, pv,
nvl(cpv, lag(cpv, 1, cpv) ignore nulls over (partition by a, b, c order by dv)) new_pv
from (
select a, b, c, dv, pv, ppv, case when rn = 1 or abs((ppv - pv)/pv) > .01 then pv end cpv
from (
select a, b, c, datevalue dv, pricevalue pv,
row_number() over (partition by a, b, c order by datevalue) rn,
lag(pricevalue) over (partition by a, b, c order by datevalue) ppv
from table1))
它應該比@LukStorms 遞歸解決方案更快,這很好並且也有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.