如何识别SQL表中的逻辑重复项

时间:2015-06-12 16:28:11

标签: sql-server

我在SQL Server 2008中工作。我有一个非常简单的表,用于保存单元测试的数据。我们称之为table_A。它只有3列:col_1,col_2和col_3因为它用于单元测试,所有3列都有数据类型varchar(255)。没有定义主键,索引或任何其他约束。

col_1和col_2包含我的自然键。我想确定此表中是否有任何重复的自然键。我知道至少有一项很好的技术。这是ROW_NUMBER,OVER,PARTITION BY,ORDER BY技术。另一个我不确定的是:

SELECT *
FROM table_A
WHERE
col_1 + ' ' + col_2
IN
(
SELECT
col_1 + ' ' + col_2
FROM table_A
GROUP BY col_1, col_2
HAVING COUNT(1) > 1
)

这个其他技术会在每个实例中返回与ROW_NUMBER技术相同的结果吗?如果是这样,性能是否与ROW_NUMBER技术大致相同?

4 个答案:

答案 0 :(得分:5)

比较查询计划:

navigator.camera.getPicture(function (fileUrl) {

    // just grab this here
    dataUrl = fileUrl;

    window.resolveLocalFileSystemURL(fileUrl, function (fileEntry) {

        fileEntry.file(function (file) {
            // Do your other work here
            // ...
        });
    });
}, function (error) {
alert(error);
}, {
    quality: 40,
    destinationType: Camera.DestinationType.FILE_URI,
    sourceType: Camera.PictureSourceType.CAMERA,
    encodingType: Camera.EncodingType.JPEG,
    saveToPhotoAlbum: false    
});

不要使用密钥连接。它无法区分这两行:

--Windowing Functions (faster)
WITH cte AS (
  SELECT *
    ,c= COUNT(*) OVER (PARTITION BY col_1,col_2)
  FROM MyTable
)
SELECT *
FROM cte
WHERE c > 1;

--Inner Join (slower)
SELECT t1.*
FROM MyTable t1
INNER JOIN (
  SELECT
    col_1
   ,col_2
  FROM MyTable
  GROUP BY col_1,col_2
  HAVING COUNT(*) > 1
) t2
ON (
      t1.col_1 = t2.col_1 
  AND t1.col_2 = t2.col_2
);

--Corellated Subquery (slower)
SELECT t1.*
FROM MyTable t1
WHERE EXISTS (
  SELECT 1
  FROM MyTable t2
  WHERE t1.col_1 = t2.col_1 
    AND t1.col_2 = t2.col_2
  GROUP BY col_1,col_2
  HAVING COUNT(*) > 1
);

在两行中INSERT MyTable (col_1,col_2) VALUES ('a b','c' ) ,('a' ,'b c')

答案 1 :(得分:1)

这是另一种可以使用索引的可能解决方案:

SELECT a.* 
FROM table_A a
WHERE EXISTS 
  (
      SELECT b.col_1, b.col_2 
      FROM table_A b 
      WHERE a.col_1 = b.col_1 and a.col_2=b.col_2 
      GROUP BY b.col_1, b.col_2 
      HAVING COUNT(*) > 1
   )

答案 2 :(得分:0)

关于效果:

在这种情况下,您使用“+”运算符创建一个人工字段,然后将其用于查找。

此方法最终会降低查询速度,因为无法查找索引,并且优化程序无法正常工作。坚持使用更多面向集合的方法总是更好。如果不完全了解您的其他解决方案,使用OVER和PARTION BY听起来已经非常好了。

答案 3 :(得分:0)

您可以像这样使用ROW_NUMBER()

SELECT
    *
FROM (
    SELECT
        *, 
        ROW_NUMBER() OVER (PARTITION BY col_1, col_2 ORDER BY col_1) As rn
    Table_A ) a
WHERE
     a > 1