SQL 只返回重复行

56
我有一个查询返回以下行:
StateId, OrderId, OrderTime, PermitId
我需要只返回完全重复的行,因此每个记录必须与其他记录完全相同才能被视为重复。我想同时返回这两个记录。这些记录与许多没有重复记录的记录混在一起......
有什么想法吗?
3个回答

79

首先,识别重复项。其次,连接回来以提取这些行。

非聚合(或非窗口/排名)自连接形成部分交叉连接,并为任何键集提供重复项的平方。包括非重复项。毕竟1 x 1 = 1。

SELECT
    t2.*
FROM
    (
    SELECT 
       StateId, OrderId, OrderTime, PermitId
    FROM
       myTable
    GROUP BY
       StateId, OrderId, OrderTime, PermitId
    HAVING
       COUNT(*) >= 2
    ) T1
    JOIN
    mytable T2 ON T1.StateId = T2.StateId AND T1.OrderId = T2.OrderId AND
                   T1.OrderTime = T2.OrderTime AND T1.PermitId = T2.PermitId

3
这是一个非常成功的任务。 - Ammamon

26

一般来说,如果你只是想查看哪些行具有这些值的重复项...

SELECT StateId, OrderId, OrderTime, PermitId, COUNT(*) FROM Foo
GROUP BY StateId, OrderId, OrderTime, PermitId
HAVING COUNT(*) > 1

5
OP 明确表示需要在结果集中包含重复的行。 - Pablo Santa Cruz

11

如果你的数据库服务器支持子查询,那么一种可能性是:

select * from your_table
 where (StateId, OrderId, OrderTime, PermitId) in
  ( select StateId, OrderId, OrderTime, PermitId
      from your_table
     group by StateId, OrderId, OrderTime, PermitId
    having count(1) > 1 )

1
这在某些关系型数据库中会失败,因为IN子句有多个列。使用EXISTS或INTERSECT则可以。 - gbn
1
OP没有说明使用的是哪种关系型数据库管理系统。它肯定在某些服务器上能够工作。 - Pablo Santa Cruz
1
哎,哪个关系型数据库不支持带有多列的IN子句? - Ronnis
1
@Ronnis:我认为SQLServer不支持它。但是PostgreSQL、MySQL和其他几个支持。 - Pablo Santa Cruz
1
我改正了。我在mysql和oracle中一直在使用它,但我只是短暂地与SQL Server交往过,我猜我从未在那个项目中使用过那种语法。 - Ronnis
1
@Pablo Santa Cruz,@Ronnis:在我看来,这是一种相当丑陋的语法。最好使用EXISTS或INTERSECT。如果您使用NOT IN,则其语义与NOT EXISTS或EXCEPT非常不同。最后,在SQL Server上,IN和EXISTS生成相同的计划。 - gbn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接