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


415

您可以通过SQL语句帮助我在多个字段中查找重复项吗?

例如,用伪代码:

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

从上面的陈述中,如果有多次出现,我想选择除第一个以外的所有记录


3
您的伪代码是模棱两可的,而且您不按不希望使用的顺序来定义顺序。我建议您提供一些示例数据。
Unreason

Answers:


840

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

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

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

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

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


42

您提到“第一个”,因此我假设您对数据有某种排序。假设您的数据按某个字段排序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)

17

我喜欢使用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标记。很高兴我的建议仍然有效。
尼克·瓦卡罗

1
出色的解决方案,因为它还会返回需要从该表中删除的行
Realto619

1
它有助于将PARTITION BY字段列表视为PK字段的列表
bkwdesign 2014年

6

要查看重复的值:

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

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列。


1
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    

0

尝试使用此查询来获取每个SELECT语句的sepratley计数:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.