2017-09-04 75 views
0

我想基于来自各个表的多个列来识别db中的重复项。在下面的示例中,1 & 5和2 & 4是重复的 - 因为所有四列具有相同的值。如何使用sql识别这些记录?当我必须根据单个列标识重复项时,我使用了> 1的计数,但我不确定如何根据多列标识它们。但是,我看到,当我根据所有4列进行计数> 1时,#3和#6显示出来,它们在技术上不是按照我的要求重复的。基于多列识别重复项

T1

ID | Col1 | Col2 
---| --- | --- 
1 | A | US 
2 | B | FR 
3 | C | AU 
4 | B | FR 
5 | A | US 
6 | D | UK 

T2

ID | Col1 
---| ---    
1 | Apple 
1 | Kiwi 
2 | Pear 
3 | Banana 
3 | Banana 
4 | Pear 
5 | Apple 

T3

ID | Col1  
---| --- 
1 | Spinach 
1 | Beets 
2 | Celery 
3 | Radish 
4 | Celery 
5 | Spinach 
6 | Celery 
6 | Celery 

我的预期的结果将是:

1 A US Apple Spinach 
5 A US Apple Spinach 
2 B FR Pear Celery 
4 B FR Pear Celery 
+0

在组中使用'和condition' –

+0

您的预期结果是什么? – zarruq

+0

更新了我的问题。 – Skn

回答

0

问题是您的结果集需要包含唯一的ID列。所以一个简单的GROUP BY ... HAVING不会削减它。这会工作。

with cte as 
    (select t1.id 
       , t1.col1 as t1_col1 
       , t1.col2 as t1_col2 
       , t2.col1 as t2_col1 
       , t3.col1 as t3_col1 
     from t1 
      join t2 on t1.id = t2.id 
      join t3 on t1.id = t3.id 
    ) 
select cte.* 
from cte 
where (t1_col1, t1_col2, t2_col1, t3_col1) in 
     (select t1_col1, t1_col2, t2_col1, t3_col1 
     from cte 
     group by t1_col1, t1_col2, t2_col1, t3_col1 having count(*) > 1) 
/

的使用子查询分解语法是可选的,但我觉得它有用的信号,即子查询中使用一个以上的查询。


“我所遇到的另一种情形中的数据,某些ID的在T2和T3相同的值,并且它们显示为的DUP”。

子表中重复的ID会导致连接子查询中的笛卡尔积,这会在主结果集中导致误报。理想情况下,您应该能够通过在这些表上引入额外的过滤器来移除不需要的行。但是,如果数据质量这么差,有没有有效的规则,你将不得不求助于distinct

with cte as ( 
    select t1.id 
     , t1.col1 as t1_col1 
     , t1.col2 as t1_col2 
      , t2.col1 as t2_col1 
      , t3.col1 as t3_col1 
    from t1 
     join (select distinct id, col1 from t2) t2 on t1.id = t2.id 
     join (select distinct id, col1 from t3) t3 on t1.id = t3.id 
) ... 
+0

我在数据中遇到了另一种情况,其中一些ID在T2和T3中具有相同的值,并且它们显示为dups。 – Skn

+0

我这样做了,请检查ID 3和6. 3和6不是我的要求。 – Skn

0

可以group by子句中添加的所有列,而您要查找的重复和然后写入计数条件中有圣诞老人

select t1.id,t1.col1,t2.col2,t2.col3,t3.col4 from t1 join t2 on t1.id=t2.id join t3 on t3.id=t1.id where (t1.col1,t2.col2,t2.col3,t3.col4) in (
    select t1.col1,t2.col2,t2.col3,t3.col4 
    from t1 join t2 on t1.id=t2.id join t3 on t3.id=t1.id 
    group by t1.col1,t2.col2,t2.col3,t3.col4 
    having count(*) >1 ) 
+0

你已经跳过了加入多个表的问题。这意味着您的解决方案无法处理数据中的其他褶皱。 – APC

+0

@APC OP并没有在第一时间提到no.of表,他在2小时后改变了它。总之我会相应地改变它 – Rams

0

为了您的样本数据,你可以使用这个所有inner join-ing三个表,并使用如下,在短短group by tA.Col1 having count(tA.Col1)>1where条款子查询,以获得您想要的结果实现。

SELECT t1.ID, 
     t1.Col1, 
     t1.Col2, 
     t2.Col1, 
     t3.Col1 
FROM table1 t1 
JOIN table2 t2 ON t1.ID = t2.ID 
JOIN table3 t3 ON t1.ID = t3.ID 
WHERE t1.Col1 IN 
    (SELECT tA.Col1 
    FROM table1 tA 
    GROUP BY tA.Col1 
    HAVING count(tA.Col1)>1) 
ORDER BY t1.ID; 

结果

ID Col1 Col2 Col1 Col1 
----------------------------------- 
1 A  US  Apple Spinach 
2 B  FR  Pear Celery 
4 B  FR  Pear Celery 
5 A  US  Apple Spinach 

您可以查看演示here

希望这会有所帮助。

+0

这个解决方案只有在't1.col1'和't1 .col2'。我同意适用于发布的样本测试数据,但是您假设它适用于真实数据 – APC

+0

@APC:这就是为什么我的答案的第一行是“对于您的示例数据”:-) – zarruq