选择语句以查找某些字段的重复项

Posted

技术标签:

【中文标题】选择语句以查找某些字段的重复项【英文标题】:Select statement to find duplicates on certain fields 【发布时间】:2011-05-24 23:06:50 【问题描述】:

您能帮我用 SQL 语句查找多个字段的重复项吗?

例如,在伪代码中:

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

从上面的语句如果有多次出现我想选择除了第一个之外的每条记录

【问题讨论】:

你的伪代码是模棱两可的,而且你没有定义你不想要第一个的顺序。我建议你提供一些示例数据。 【参考方案1】:

要获取有多个记录的字段列表,可以使用..

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

查看此链接以获取有关如何删除行的更多信息。

http://support.microsoft.com/kb/139444

在使用上面链接中的方法之前,应该有一个标准来决定如何定义“第一行”。基于此,如果需要,您将需要使用 order by 子句和子查询。如果您可以发布一些示例数据,那真的很有帮助。

【讨论】:

【参考方案2】:

您提到“第一个”,所以我假设您对数据有某种排序。假设您的数据按某个字段ID 排序。

此 SQL 应该会为您提供除第一个之外的重复条目。它基本上选择具有(a)相同字段和(b)较低ID的另一行的所有行。性能不会很好,但它可能会解决您的问题。

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

【讨论】:

【参考方案3】:

如果您使用的是 SQL Server 2005 或更高版本(并且您的问题的标签指示 SQL Server 2008),如果使用连接对于某些人来说不太理想或不切实际,您可以使用排名函数返回第一个记录之后的重复记录原因。以下示例显示了这一点,它也适用于检查列中的空值。

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

运行此示例后请注意,每个“组”中的第一条记录都被排除在外,并且具有空值的记录得到了正确处理。

如果您没有可用于对组内的记录进行排序的列,则可以使用 partition-by 列作为 order-by 列。

【讨论】:

【参考方案4】:

这是我喜欢的一个有趣的 SQL Server 2005 解决方案。我将假设“对于除第一条记录之外的每条记录”,您的意思是还有另一个“id”列,我们可以使用它来识别哪一行是“第一条”。

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

【讨论】:

刚刚注意到 SQL Server 2008 标签。很高兴我的建议仍然有效。 优秀的解决方案,因为它还返回需要从相关表中删除的行 将 PARTITION BY 字段列表视为 PK 字段列表会有所帮助【参考方案5】:

查看重复值:

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1

【讨论】:

【参考方案6】:
CREATE TABLE #tmp
(
    sizeId Varchar(MAX)
)

INSERT  #tmp 
    VALUES ('44'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46'),
        ('44,45,46')


SELECT * FROM #tmp
DECLARE @SqlStr VARCHAR(MAX)

SELECT @SqlStr = STUFF((SELECT ',' + sizeId
              FROM #tmp
              ORDER BY sizeId
              FOR XML PATH('')), 1, 1, '') 


SELECT TOP 1 * FROM (
select items, count(*)AS Occurrence
  FROM dbo.Split(@SqlStr,',')
  group by items
  having count(*) > 1
  )K
  ORDER BY K.Occurrence DESC    

【讨论】:

【参考方案7】:

试试这个查询来分别统计每个 SELECT 语句:

select field1,count(field1) as field1Count,field2,count(field2) as field2Counts,field3, count(field3) as field3Counts
from table_name
group by field1,field2,field3
having count(*) > 1

【讨论】:

【参考方案8】:

尝试此查询以查找多个字段上的重复记录

SELECT a.column1, a.column2
FROM dbo.a a
JOIN (SELECT column1, 
       column2, count(*) as countC
FROM dbo.a 
GROUP BY column4, column5
HAVING count(*) > 1 ) b
ON a.column1 = b.column1
AND a.column2 = b.column2

【讨论】:

以上是关于选择语句以查找某些字段的重复项的主要内容,如果未能解决你的问题,请参考以下文章

如何按 RDD 中的选定字段数进行分组,以查找基于这些字段的重复项

基于两个字段的某些字段选择行并删除重复项并限制为前十名?

如何用sql 语句查找一个表里的两个字段重复的记录

用SQL语句,删除掉重复项只保留一条

SQL查询语句,怎样查询重复数据

删除空格和特殊字符后,ElasticSearch会查找所有重复项