Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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
Mysql SQL:如何根据条件从表中删除行_Mysql_Sql_Sql Delete - Fatal编程技术网

Mysql SQL:如何根据条件从表中删除行

Mysql SQL:如何根据条件从表中删除行,mysql,sql,sql-delete,Mysql,Sql,Sql Delete,我有下表: tbl source type date --- --- --- google A 2010-02-25 google A 2013-04-11 facebook C 2008-10-22 facebook C 2007-01-28 我只想保留每个源的一个条目,标准是使用mindate group by source选择源元组。该表由数百万条记录组成,我正在寻找一种有效的方法来删除冗余记

我有下表:

tbl
source    type    date
---       ---     ---
google    A       2010-02-25
google    A       2013-04-11
facebook  C       2008-10-22
facebook  C       2007-01-28

我只想保留每个源的一个条目,标准是使用mindate group by source选择源元组。该表由数百万条记录组成,我正在寻找一种有效的方法来删除冗余记录

在MySQL中,您可以使用连接:

我认为提高效率的唯一方法是将聚合结果存储在子查询中并向其中添加索引

我还可以补充一点,无论确定要删除的行的计算是什么,在一个表中删除很多行都是低效的。通常,我建议采用三步方法:

编写查询以生成所需的表,并将结果存储在临时表中。 截断原始表。 重新插入数量少得多的行。
在MySQL中,您可以使用连接:

我认为提高效率的唯一方法是将聚合结果存储在子查询中并向其中添加索引

我还可以补充一点,无论确定要删除的行的计算是什么,在一个表中删除很多行都是低效的。通常,我建议采用三步方法:

编写查询以生成所需的表,并将结果存储在临时表中。 截断原始表。 重新插入数量少得多的行。
在Microsoft SQL中,您可以尝试此操作

;
WITH cte 
        AS (SELECT ROW_NUMBER() OVER (PARTITION BY source, type
                                        ORDER BY createdate) RN
            FROM   tbsource)
DELETE FROM cte
WHERE  RN > 1;

在Microsoft SQL中,您可以尝试此操作

;
WITH cte 
        AS (SELECT ROW_NUMBER() OVER (PARTITION BY source, type
                                        ORDER BY createdate) RN
            FROM   tbsource)
DELETE FROM cte
WHERE  RN > 1;

将标识列作为序列号添加到复制表中,该序列号充当行唯一标识自动递增升序:

 alter table tbl add sno int identity(1,1)
此查询仅选择具有mindate的非重复行:

(select min(date),sno From tbl group by source) 
所以sno等于1和4

现在使用此表进行连接,并删除重复的连接记录。sno为null

delete E from tbl E
    left join
    (select min(date),sno From tbl group by source) T on E.sno=T.sno
where T.sno is null

根据此链接的方法3改编的解决方案:

将标识列作为序列号添加到重复表中,该序列号充当行唯一标识自动递增升序:

 alter table tbl add sno int identity(1,1)
此查询仅选择具有mindate的非重复行:

(select min(date),sno From tbl group by source) 
所以sno等于1和4

现在使用此表进行连接,并删除重复的连接记录。sno为null

delete E from tbl E
    left join
    (select min(date),sno From tbl group by source) T on E.sno=T.sno
where T.sno is null

根据此链接的方法3改编的解决方案:

此表是否有任何唯一标识符,即主键、id字段等?@ChrisJ-nah,它没有。此表是否有任何唯一标识符,即主键、id字段等?@ChrisJ-nah,它没有。@GordonLinoff,对不起。问题不包含MySQL的标签。有一个MySQL标签,但如果它是应该的,可能也应该在标题中。@mikato,是的,正确!甚至还有SQL标记,这使得这个问题被看作是一个通用的问题。什么是Microsoft SQL?您可能指的是Microsoft SQL Server或Microsoft TSQL。这并不是吹毛求疵,因为MS Access有一种与MSSQL不同的SQL方言,而且两者都是MS产品。并跨越多个接口。@Parfait,你说得对。我这里指的是Microsoft SQL Server或Transact-SQL。@GordonLinoff,对不起。问题不包含MySQL的标签。有一个MySQL标签,但如果它是应该的,可能也应该在标题中。@mikato,是的,正确!甚至还有SQL标记,这使得这个问题被看作是一个通用的问题。什么是Microsoft SQL?您可能指的是Microsoft SQL Server或Microsoft TSQL。这并不是吹毛求疵,因为MS Access有一种与MSSQL不同的SQL方言,而且两者都是MS产品。并跨越多个接口。@Parfait,你说得对。我这里指的是Microsoft SQL Server或Transact-SQL。感谢您提供此代码段,它可能会提供一些有限的即时帮助。通过说明为什么这是一个很好的问题解决方案来正确解释它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的答案中添加一些解释,包括您所做的假设。感谢您提供此代码片段,它可能会提供一些有限的、即时的帮助。通过说明为什么这是一个很好的问题解决方案来正确解释它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的回答中添加一些解释,包括您所做的假设。