如何找出哪些行(如果有)在列中具有非唯一值?

时间:2013-10-12 19:58:51

标签: sql-server sql-server-2012

我的SQL Server 2012数据库中有以下表格:

CREATE TABLE [dbo].[Problem](
    [ProblemId] [int] IDENTITY(1,1) NOT NULL,
    [SubTopicId] [int] NOT NULL,
    [ReferenceId] [int] NOT NULL,
    [ProblemStatusId] [int] NOT NULL,
    [Locator] [nvarchar](50) NULL
)

定位器应该是唯一的,但我认为在某些情况下,多个行具有相同的定位器值。我怎样才能知道是否是这种情况,如果是,那我该如何识别行?

4 个答案:

答案 0 :(得分:2)

如果要执行快速和脏检查,可以尝试在UNIQUE上添加Locator约束(或索引)。如果成功,则没有重复项。如果它失败了,你就有了。

上面的问题是SQL-Server以相当非标准的方式处理NULL值,即使你有2行NULL而没有其他真正的约束/索引创建也会失败重复的值。为避免这种情况(如果您想允许多个Null但没有重复的非空值),您可以使用过滤的唯一索引进行检查:

CREATE UNIQUE INDEX Locator_UQ           -- choose a name for the index
ON Problem (Locator)
WHERE Locator IS NOT NULL ;

要找到重复项(并同时检查),一种方法是:

SELECT *
FROM
  ( SELECT *,
           Cnt = COUNT(*) OVER (PARTITION BY Locator)
    FROM Problem
  ) AS p
WHERE Cnt > 1 
ORDER BY Locator, ProblemId ;

如果上述内容返回0行,则Locator中没有重复项。

答案 1 :(得分:2)

select * from table where Locator in 
   (
    select Locator from table group by Locator having count(*) > 1
   )

答案 2 :(得分:0)

选择定位器,通过定位器从dbo.Problem组中计数(*)为出现

- 使用where子句,您可以过滤重复的定位器,如

出现> 1

答案 3 :(得分:0)

如果你有大量数据,那么你可以试试这个解决方案:

DECLARE @MyTable TABLE
(
    [ProblemId] [int] IDENTITY(1,1) NOT NULL,
    [SubTopicId] [int] NOT NULL,
    [Locator] [nvarchar](50) NULL
);

INSERT  @MyTable (SubTopicId, Locator)
SELECT  11, 'A' UNION ALL
SELECT  11, 'B' UNION ALL
SELECT  22, 'C' UNION ALL
SELECT  44, 'C' UNION ALL
SELECT  33, 'D' UNION ALL
SELECT  55, 'D'  UNION ALL
SELECT  22, 'D'  UNION ALL
SELECT  22, NULL;

SET STATISTICS IO ON;

SELECT  *
FROM
(
    SELECT  x.*,
            ROW_NUMBER() OVER(PARTITION BY x.Locator ORDER BY x.ProblemId ASC) AS RowNumAsc,
            ROW_NUMBER() OVER(PARTITION BY x.Locator ORDER BY x.ProblemId DESC) AS RowNumDesc
    FROM    @MyTable x
) src
WHERE   NOT(src.RowNumAsc = 1 AND src.RowNumDesc = 1);