Oracle sql 查询 GROUP BY、ORDER BY 并删除每个 ID 最旧的记录
Oracle sql query to GROUP BY, ORDER BY and delete the oldest records per ID
我想编写一个 oracle sql 查询来保留按 TIMESTAMP 排序的前三个最新记录,并删除每个 MACHINE_ID 的其余记录。
我想知道我能多高效地做到这一点。希望你能理解我的问题!!
下面以table为例。在sql查询中可以过滤掉所有USERFILE = 0的记录。
** 之后的结果 - 按 MACHINE_ID 分组并按 TIMESTAMP desc 排序 **
每 MACHINE_ID 保留前 3 条最新记录并删除最旧的记录后,最终结果应该是
您可以对每台机器的行进行编号,然后删除所有编号大于 3 的行。理想情况下,我们可以简单地从查询中删除,但我收到 ORA-01732:数据操作操作在此视图上不合法在 Oracle 19c 中尝试此操作时。
因此我们需要两个步骤:
- 查找行
- 删除行
使用rowid快速再次访问行的语句:
delete from mytable
where rowid in
(
select rowid
from
(
select
rowid,
row_number() over (partition by machine_id order by timestamp desc) as rn
from mytable
)
where rn > 3
);
一种方法是:
delete from t
where t.timestamp not in (select t2.timestamp
from t t2
where t2.machine_id = t.machine_id
order by t2.timestamp desc
fetch first 3 rows only
);
为了性能,您需要 (machine_id, timestamp desc)
上的索引。
我想编写一个 oracle sql 查询来保留按 TIMESTAMP 排序的前三个最新记录,并删除每个 MACHINE_ID 的其余记录。 我想知道我能多高效地做到这一点。希望你能理解我的问题!!
下面以table为例。在sql查询中可以过滤掉所有USERFILE = 0的记录。
** 之后的结果 - 按 MACHINE_ID 分组并按 TIMESTAMP desc 排序 **
每 MACHINE_ID 保留前 3 条最新记录并删除最旧的记录后,最终结果应该是
您可以对每台机器的行进行编号,然后删除所有编号大于 3 的行。理想情况下,我们可以简单地从查询中删除,但我收到 ORA-01732:数据操作操作在此视图上不合法在 Oracle 19c 中尝试此操作时。
因此我们需要两个步骤:
- 查找行
- 删除行
使用rowid快速再次访问行的语句:
delete from mytable
where rowid in
(
select rowid
from
(
select
rowid,
row_number() over (partition by machine_id order by timestamp desc) as rn
from mytable
)
where rn > 3
);
一种方法是:
delete from t
where t.timestamp not in (select t2.timestamp
from t t2
where t2.machine_id = t.machine_id
order by t2.timestamp desc
fetch first 3 rows only
);
为了性能,您需要 (machine_id, timestamp desc)
上的索引。