删除 SQL 中的重复行

Posted

技术标签:

【中文标题】删除 SQL 中的重复行【英文标题】:Removing Duplicate Rows in SQL 【发布时间】:2018-06-01 20:46:30 【问题描述】:

我有一个查询,它返回具有多个“移动”日期的设备列表。我只想要最旧的日期条目。我使用 MIN 函数给了我最早的日期,但我仍然收到多个条目(但是,我得到的比以前少)。我试图获得更精确的 JOIN,但无法再缩小字段范围。

如果您查看屏幕截图,前三行具有相同的“wonum”,但三个不同的“移动日期”。我在想,如果我能以某种方式从这三个行中取出最旧的“移动日期”并删除其他行,那将给我我正在寻找的结果。但是,我没有足够的技能来做到这一点(我现在只在 SQL 中工作了几个月)。那会起作用吗,还是有更好的方法来缩小我的结果范围?我想知道我是否需要执行某种子查询来获得我需要的东西。

我环顾四周,但找不到任何可以让我按照我想要的方式删除一行数据的东西。我似乎也找不到我的 MIN 函数不再减少数据的原因。下面是我目前正在使用的代码。感谢您提供的任何帮助。

SELECT wo.wonum, wo.location, wo.statusdate, wo.status, l.subcontractor,
    wo.description, MIN(ast.datemoved) AS 'Moved Date'
FROM workorder wo
        JOIN locations l ON wo.location = l.location
        JOIN asset a ON wo.location = a.location 
          -- AND wo.assetnum = a.assetnum
        JOIN assettrans ast ON a.assetnum = ast.assetnum
          -- AND a.assetid = ast.assetid
WHERE wo.description LIKE '%deteriorating%'
        AND wo.status != 'close'
GROUP BY wo.wonum, wo.location, wo.statusdate, 
  wo.status, l.subcontractor, wo.description
ORDER BY wo.wonum;

DBV SQL Query Result

更新:Table Data

【问题讨论】:

你能发布查询的结果吗?如果按列出的列分组,那么这 7 列中不会有重复的行。 从图中显示的他的数据集中,他有多个不完全相同的列,因此分组只是没有任何作用。 为了提供帮助,我们可能需要了解有关此连接中其他表的更多信息。奇怪的是,您将不得不使用子查询来分别从其余数据中获取最小值。 assettrans 表中是否还有其他唯一标识符? 我搜索了其他表并加入了我能找到的任何表。我实际上不需要“assetnum”表;我只是用它来将“assetid”表加入到查询中。似乎有很多列没有交叉到我正在使用的任何其他表中。 @TaRan,如果您需要帮助,请提供每个表格的表格布局,至少要显示您正在使用的列。如果您使用的是一个表中的数据,而另一个表中的数据也显示在另一个表中 【参考方案1】:

您需要在子查询内的 join 语句中进行分组(未测试,但您会明白的):

替换

JOIN assettrans ast ON a.assetnum = ast.assetnum

inner join
(
    select ast.assetnum,MIN(ast.datemoved) AS 'Moved Date' 
    from assettrans ast  
    group by ast.assetnum
) grouped
on a.assetnum = grouped.assetnum

所以完整的查询看起来像:

SELECT wo.wonum, wo.location, wo.statusdate, wo.status, l.subcontractor,
    wo.description, grouped.MovedDate
FROM workorder wo
        JOIN locations l ON wo.location = l.location
        JOIN asset a ON wo.location = a.location 
        INNER JOIN
        (
           select ast.assetnum,MIN(ast.datemoved) AS MovedDate 
           from assettrans ast  
           group by ast.assetnum
        ) grouped
        on a.assetnum = grouped.assetnum
    WHERE wo.description LIKE '%deteriorating%'
            AND wo.status != 'close'
    ORDER BY wo.wonum;

【讨论】:

我尝试了您的解决方案,但得到的结果与不使用子查询时的结果相同;我用您提供的代码替换了我的“assettrans”连接。我尝试在原始查询中移动它并做了一些小的调整,但我似乎总是得到相同的结果。我应其他用户的要求用新图像更新了我的原始帖子。也许会有所帮助。 请查看我编辑的帖子以获取完整的 sql 示例。没有测试过,但应该是正确的。 感谢您的帮助。看起来我在选择语句中缺少“group.MovedDate”,这就是为什么子查询对我不起作用的原因。谢谢你帮我解决这个问题。这有助于我学习子查询。 :)【参考方案2】:

在生产中使用前请测试

--如果你有 id 列并留下最旧的记录

从 MyTable T1、MyTable T2 中删除 T1 其中 T1.dupField = T2.dupField (如果适用,请添加更多过滤器) 和 T1.uniqueField > T2.uniqueField

--如果要删除新的“已移动日期”并保留最旧的日期

从 MyTable T1、MyTable T2 中删除 T1 其中 T1.dupField = T2.dupField (如果适用,请添加更多过滤器) 和 T1.Moved 日期 > T2.Moved 日期

【讨论】:

这应该是我原始查询中的子查询吗?我不确定如何使用它。看起来这是从数据库本身的表中删除条目;这不是我想要做的。我想从我对数据库的最终查询中删除行(如果有意义的话)。

以上是关于删除 SQL 中的重复行的主要内容,如果未能解决你的问题,请参考以下文章

sql 删除表中的重复行

删除 SQL 中的重复行

如何删除SQL Server中的重复行?

如何使用 UPDATE 合并和删除 SQL 中的重复行?

根据google BigQuery SQL中的属性删除重复行

尝试删除 SQL Server 中的重复行,其中差异是日期或批号