Oracle SQL - 根据条件删除记录子集
Oracle SQL - Delete subset of records based on criteria
我有以下table
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
其余全部删除。
table中有很多项目和位置,我需要为item/location
的组合保留3条记录
您可以使用 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;
这 returns 3 行所有 item/location 对。如果您只考虑一对,您可以使用:
select t.*
from t
where item = ? and location = ?
order by effective_date desc
fetch first 3 rows only;
您想使用 ROW_NUMBER
分析函数查找最近三行之后的行,然后使用 ROWID
伪列与 DELETE
语句关联:
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', 11001, DATE '2019-10-08', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2019-10-04', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2018-01-01', 2 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2017-12-04', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2017-03-02', 500 FROM DUAL;
然后删除后:
SELECT * FROM table_name;
输出:
ITEM
LOCATION
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
db<>fiddle here
我有以下table
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
其余全部删除。
table中有很多项目和位置,我需要为item/location
的组合保留3条记录您可以使用 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;
这 returns 3 行所有 item/location 对。如果您只考虑一对,您可以使用:
select t.*
from t
where item = ? and location = ?
order by effective_date desc
fetch first 3 rows only;
您想使用 ROW_NUMBER
分析函数查找最近三行之后的行,然后使用 ROWID
伪列与 DELETE
语句关联:
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', 11001, DATE '2019-10-08', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2019-10-04', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2018-01-01', 2 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2017-12-04', 1 FROM DUAL UNION ALL
SELECT '00139259', 11001, DATE '2017-03-02', 500 FROM DUAL;
然后删除后:
SELECT * FROM table_name;
输出:
ITEM LOCATION 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
db<>fiddle here