从 sql 中删除行号大于指定的每个组的寄存器
Delete registers with rownumber greater than specified for each group got from sql
我有 table 个人在博客上发表评论。我需要在 table 中为每个人留下最后 10 条评论,并删除较旧的评论。假设列是:
- personId
- 评论编号
- 来自评论的日期
我知道如何处理多个查询,但不是只处理一个查询(允许任何子查询)和任何数据库
与:
select personId from PeopleComments
group by personId
having count(*) >10
我会获取评论超过 10 条的人员 ID,但我不知道如何从那里获取评论 ID 并将其删除
谢谢!
您需要一个计算以下评论的相关子查询:
delete from peoplecomments pc
where
(
select count(*)
from peoplecomments pc2
where pc2.personid = pc.personid
and pc2.datefromcomment > pc.datefromcomment
) >= 10; -- at least 10 newer comments for the person
顺便说一句:虽然看起来我们可以简单地对行进行编号并通过
进行相应删除
delete from
(
select
pc.*, row_number() over (partition by personid order by datefromcomment desc) as rn
from peoplecomments pc
)
where rn > 10;
Oracle 不允许这样做并给了我们 ORA-01732: data manipulation operation not legal on this view
.
在我的另一个回答中,DBMS 必须为 table 中的每一行查找并计算行数。这可能很慢。最好找到我们要保留的所有行一次,然后删除其他行。因此这个额外的答案。
从版本 12c 开始,以下适用于 Oracle:
delete from peoplecomments
where rowid not in
(
select rowid
from peoplecomments
order by row_number() over (partition by personid order by datefromcomment desc)
fetch first 10 rows with ties
);
除了 ROWID
这是标准的 SQL。
在其他支持 window 函数和 FETCH WITH TIES
的 DBMS 中:
- 如果您的 table 有一个单列主键,您将用它替换
ROWID
。
- 如果您的 table 有复合主键,您可以使用
where (col1, col2) not in (select col1, col2 ...)
,前提是您的 DBMS 支持此语法。
我有 table 个人在博客上发表评论。我需要在 table 中为每个人留下最后 10 条评论,并删除较旧的评论。假设列是:
- personId
- 评论编号
- 来自评论的日期
我知道如何处理多个查询,但不是只处理一个查询(允许任何子查询)和任何数据库
与:
select personId from PeopleComments
group by personId
having count(*) >10
我会获取评论超过 10 条的人员 ID,但我不知道如何从那里获取评论 ID 并将其删除
谢谢!
您需要一个计算以下评论的相关子查询:
delete from peoplecomments pc
where
(
select count(*)
from peoplecomments pc2
where pc2.personid = pc.personid
and pc2.datefromcomment > pc.datefromcomment
) >= 10; -- at least 10 newer comments for the person
顺便说一句:虽然看起来我们可以简单地对行进行编号并通过
进行相应删除delete from
(
select
pc.*, row_number() over (partition by personid order by datefromcomment desc) as rn
from peoplecomments pc
)
where rn > 10;
Oracle 不允许这样做并给了我们 ORA-01732: data manipulation operation not legal on this view
.
在我的另一个回答中,DBMS 必须为 table 中的每一行查找并计算行数。这可能很慢。最好找到我们要保留的所有行一次,然后删除其他行。因此这个额外的答案。
从版本 12c 开始,以下适用于 Oracle:
delete from peoplecomments
where rowid not in
(
select rowid
from peoplecomments
order by row_number() over (partition by personid order by datefromcomment desc)
fetch first 10 rows with ties
);
除了 ROWID
这是标准的 SQL。
在其他支持 window 函数和 FETCH WITH TIES
的 DBMS 中:
- 如果您的 table 有一个单列主键,您将用它替换
ROWID
。 - 如果您的 table 有复合主键,您可以使用
where (col1, col2) not in (select col1, col2 ...)
,前提是您的 DBMS 支持此语法。