如何解决Oracle SQL - 根据条件删除记录子集
我有下表
ITEM LOCATION EFFECTIVE_DATE SELLING_RETAIL
00139259 11001 01-JUL-20 2
00139259 11001 08-OCT-19 1
00139259 11001 04-OCT-19 1
00139259 11001 01-JAN-18 2
00139259 11001 04-DEC-17 1
00139259 11001 02-MAR-17 500
我只需要按降序保留项目、位置和生效日期这三个记录。
这样我就留在了:
ITEM LOCATION EFFECTIVE_DATE SELLING_RETAIL
00139259 11001 01-JUL-20 2
00139259 11001 08-OCT-19 1
00139259 11001 04-OCT-19 1
其余的都应该删除。
表中有很多item和location,item/location的组合我需要保留3条记录
解决方法
您想使用 ROW_NUMBER
分析函数查找最近三行之后的行,然后使用 DELETE
伪列与 ROWID
语句相关联:
DELETE FROM table_name
WHERE ROWID IN (
SELECT ROWID
FROM (
SELECT ROW_NUMBER() OVER (
PARTITION BY item,location ORDER BY effective_date DESC
) AS rn
FROM table_name
)
WHERE rn > 3
)
对于您的示例数据:
CREATE TABLE TABLE_NAME ( ITEM,LOCATION,EFFECTIVE_DATE,SELLING_RETAIL ) AS
SELECT '00139259',11001,DATE '2020-07-01',2 FROM DUAL UNION ALL
SELECT '00139259',DATE '2019-10-08',1 FROM DUAL UNION ALL
SELECT '00139259',DATE '2019-10-04',DATE '2018-01-01',DATE '2017-12-04',DATE '2017-03-02',500 FROM DUAL;
然后删除后:
SELECT * FROM table_name;
输出:
项目 | 位置 | EFFECTIVE_DATE | SELLING_RETAIL |
---|---|---|---|
00139259 | 11001 | 2020-07-01 00:00:00 | 2 |
00139259 | 11001 | 2019-10-08 00:00:00 | 1 |
00139259 | 11001 | 2019-10-04 00:00:00 | 1 |
dbfiddle here
,您可以使用row_number()
:
select t.*
from (select t.*,row_number() over (partition by item,location order by EFFECTIVE_DATE desc) as seqnum
from t
) t
where seqnum <= 3;
这会为所有项目/位置对返回 3 行。如果你有一对,你可以使用:
select t.*
from t
where item = ? and location = ?
order by effective_date desc
fetch first 3 rows only;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。