删除从sql获取的每个组的行数大于指定行数的寄存器
我在一个博客上有一张人们的表格。我需要为表中的每个人留下最后10条评论,并删除旧的评论。假设列为: 拟人 评论 dateFromComment 我知道如何使用多个查询,但不能只使用一个查询,允许任何子查询和任何数据库 与:删除从sql获取的每个组的行数大于指定行数的寄存器,sql,group-by,field,sql-delete,Sql,Group By,Field,Sql Delete,我在一个博客上有一张人们的表格。我需要为表中的每个人留下最后10条评论,并删除旧的评论。假设列为: 拟人 评论 dateFromComment 我知道如何使用多个查询,但不能只使用一个查询,允许任何子查询和任何数据库 与: select personId from PeopleComments group by personId having count(*) >10 我会得到超过10条评论的人ID,但我不知道如何从那里得到评论ID并删除它们 谢谢 您需要一个包含以下注释的相关子查询
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:此视图上的数据操作不合法。您需要一个相关子查询,其中包含以下注释:
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:数据操作操作在此视图上不合法。在我的另一个回答中,DBMS必须查找并计算表中每一行的行数。这可能很慢。最好只找到一次要保留的所有行,然后删除其他行。因此,这是另一个答案 从版本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
在其他支持窗口函数和使用关系获取的DBMS中:
如果您的表有一个单列主键,则应该用它替换ROWID。
如果您的表有一个复合主键,您应该使用where col1,col2 not in select col1,col2。。。如果您的DBMS支持此语法。
在我的另一个回答中,DBMS必须为表中的每一行查找并计数行。这可能很慢。最好只找到一次要保留的所有行,然后删除其他行。因此,这是另一个答案 从版本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
在其他支持窗口函数和使用关系获取的DBMS中:
如果您的表有一个单列主键,则应该用它替换ROWID。
如果您的表有一个复合主键,您应该使用where col1,col2 not in select col1,col2。。。如果您的DBMS支持此语法。
你的数据库管理系统是什么?MySQL?SQL Server?神谕它是Oracle,但希望独立于它您的DBMS是什么?MySQL?SQL Server?神谕它的甲骨文,但希望独立于它