关于sql:查找特定列的重复行


finding duplicates rows for specified columns

本问题已经有最佳答案,请猛点这里访问。

我有下面的数据,我需要找到具有相同值的ID(值的数量也应该相同)。
这里id 1和3具有相同的值,具有不同的id,所以我想要这两个ID作为输出。
Id是4也有相同的链接,但它也有不同的值333所以我不希望这样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
id  VALUE
1   111
1   222

2   222
2   333

3   111
3   222

4   111
4   222
4   333

5       111
5       444

我尝试使用存在的查询,但它也返回5这是错误的。我正在使用oracle 11G架构。

期望输出就像

给同一个ID提供一些数字以识别重复项。

因此对于

1 111 1
1 222 1
3 111 1
3 111 1


如果只有匹配彼此所有值的ID是感兴趣的部分,那么一种方法是检查每个ID的值与那些具有相同计数的ID匹配,并检查匹配的值的数量

1
2
3
4
5
6
7
8
9
10
11
12
13
WITH R AS (
  SELECT id, COUNT(1) Dim
  FROM   Table1
  GROUP BY id
)
SELECT r1.id id_1, r2.id id_2
FROM   R r1
       INNER JOIN R r2 ON r1.dim = r2.dim
       INNER JOIN Table1 t1 ON r1.id = t1.id
       INNER JOIN Table1 t2 ON r2.id = t2.id AND t1.value = t2.value
              AND t2.id > t1.id
GROUP BY r1.id, r2.id
HAVING COUNT(1) = MAX(r1.dim);

t2.id > t1.id条件是为了避免重复该对

为了使结果集更类似于问题中的结果集,可以将先前的查询作为JOIN的基础再次使用表格

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WITH R AS (
  SELECT id, COUNT(1) Dim
  FROM   Table1
  GROUP BY id
), M AS (
  SELECT r1.id id_1, r2.id id_2
  FROM   R r1
         INNER JOIN R r2 ON r1.dim = r2.dim
         INNER JOIN Table1 t1 ON r1.id = t1.id
         INNER JOIN Table1 t2 ON r2.id = t2.id AND t1.value = t2.value
                AND t2.id > t1.id
  GROUP BY r1.id, r2.id
  HAVING COUNT(1) = MAX(r1.dim)
)
SELECT t1.id id_1, t1.value value_1, t1.id base_value
     , t2.id id_2, t2.value value_2, t1.id base_value_2
FROM   M
       INNER JOIN Table1 t1 ON m.id_1 = t1.id
       INNER JOIN Table1 t2 ON m.id_2 = t2.id AND t1.value = t2.value

SQLFiddle demo包含两个查询。

即使演示在SQLServer 2012中,查询也只使用标准命令编写。

如果OP使用MySQL,WITH中的部分需要转换为FROM子句中的子查询。


你需要SET操作。 测试集合相等的一个想法是:A减B等于B减去等于空的集合。

以下是使用PL / SQL执行此操作的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
DECLARE
  v_count_1 NUMBER;
  v_count_2 NUMBER;
BEGIN
  FOR r IN (SELECT DISTINCT id FROM my_table) LOOP
    FOR r_inner IN (SELECT DISTINCT id FROM my_table WHERE id > r.id) LOOP
      SELECT COUNT(*)
      INTO v_count_1
      FROM (SELECT VALUE FROM my_table WHERE id = r.id
            MINUS
            SELECT VALUE FROM my_table WHERE id = r_inner.id);

      SELECT COUNT(*)
      INTO v_count_2
      FROM (SELECT VALUE FROM my_table WHERE id = r_inner.id
            MINUS
            SELECT VALUE FROM my_table WHERE id = r.id);

      IF v_count_1 = 0 AND v_count_2 = 0 THEN
        dbms_output.put_line('duplicate IDs: '||r.id||' '||r_inner.id);
      END IF;
    END LOOP;
  END LOOP;
END;
/