微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle SQL - 根据条件删除记录子集

如何解决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 举报,一经查实,本站将立刻删除。