Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
删除从sql获取的每个组的行数大于指定行数的寄存器_Sql_Group By_Field_Sql Delete - Fatal编程技术网

删除从sql获取的每个组的行数大于指定行数的寄存器

删除从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并删除它们 谢谢 您需要一个包含以下注释的相关子查询

我在一个博客上有一张人们的表格。我需要为表中的每个人留下最后10条评论,并删除旧的评论。假设列为:

拟人 评论 dateFromComment 我知道如何使用多个查询,但不能只使用一个查询,允许任何子查询和任何数据库

与:

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?神谕它的甲骨文,但希望独立于它