从 SQL 表中查找部分和完全重复

Posted

技术标签:

【中文标题】从 SQL 表中查找部分和完全重复【英文标题】:Finding partial and exact duplicate from a SQL table 【发布时间】:2020-07-05 03:49:40 【问题描述】:

我正在尝试从表中读取重复项。基于 Col1 和 Col2 的值有一些部分重复,而基于 Col1、Col2 和 Col3 的值有一些完全重复,如下表所示。

Col1   Col2   Col3
1      John   100
1      John   200
2      Tom    150
3      Bob    100
3      Bob    100
4      Sam    500

我想在两个单独的输出中捕获部分重复和完全重复,并忽略不重复的行,例如 2 和 4,例如

部分重复

Col1   Col2   Col3
1      John   100
1      John   200

完全复制

Col1   Col2   Col3
3      Bob    100
3      Bob    100

用 SQL 实现这一目标的最佳方法是什么?

我尝试将自连接与 spark-sql 一起使用,但出现错误:-

val source_df = sql("select col1, col2, col3 from sample_table")
source_df.as("df1").join(inter_df.as("df2"), $"df1.Col3" === $"df2.Col3" and $"df1.Col2" === $"df2.Col2" and $"df1.Col1" === $"df2.Col1").select($"df1.Col1",$"df1.Col2",$"df1.Col3",$"df2.Col3").show()

错误

org.apache.spark.sql.catalyst.errors.package$TreeNodeException:执行,树: Exchange hashpartitioning(Col3#1957, 200)

【问题讨论】:

SELECT Col1, Col2, first(Col3) as Col3 from sample_table group BY Col1, Col2 请提供部分和完全重复的定义。 我删除了不准确的数据库标签。请仅使用您真正使用的数据库进行标记。 【参考方案1】:

对于部分重复:

SELECT * 
FROM tbl
WHERE EXISTS (
    SELECT * 
    FROM tbl t2 
    WHERE tbl.col1 = t2.col1 AND tbl.col2 = t2.col2 AND tbl.col3 <> t2.col3
)

返回:

col1    col2    col3
1       John    100
1       John    200

对于完全重复,为 col1、col2 和 col3 的每个组合添加一个唯一标识符,并查找其他记录具有相同 col1、col2 和 col3 但唯一标识符不同的情况:

;WITH cte AS (
SELECT ROW_NUMBER() OVER (PARTITION BY col1, col2, col3 ORDER BY col1, col2, col3) AS uniqueid, col1, col2, col3 
FROM tbl
)
SELECT col1, col2, col3 
FROM cte
WHERE EXISTS (
    SELECT * 
    FROM cte t2 
    WHERE cte.col1 = t2.col1 AND cte.col2 = t2.col2 AND cte.col3 = t2.col3 AND cte.uniqueid <> t2.uniqueid
)

返回:

col1    col2    col3
3       Bob     100
3       Bob     100

http://sqlfiddle.com/#!18/f1d78/2

CREATE TABLE tbl (col1 INT, col2 VARCHAR(5), col3 INT)
INSERT INTO tbl VALUES 
(1, 'John', 100), 
(1, 'John', 200), 
(2, 'Tom', 150), 
(3, 'Bob', 100), 
(3, 'Bob', 100), 
(4, 'Sam', 500)

【讨论】:

【参考方案2】:
    部分重复 - 使用exists。这是demo。
select
    *
from myTable m1
where exists (
  select
    *
  from myTable m2
  where m1.Col1 = m2.Col1
  and m1.Col2 = m2.Col2
  and m1.Col3 <> m2.Col3
)

输出:

----------------------
 Col1    Col2    Col3
----------------------
  1      John    100
  1      John    200
----------------------
    完全重复 - 您可以使用 count(*) 作为窗口函数。这是demo。
with cte as
( 
  select
    Col1,
    Col2,
    Col3,
    count(*) over (partition by Col1, Col2, Col3) as rn
  from myTable 
) 

select
  Col1,
  Col2,
  Col3
from cte    
where rn > 1  

输出:

----------------------
 Col1   Col2    Col3
----------------------
  3     Bob     100
  3     Bob     100
----------------------

【讨论】:

以上是关于从 SQL 表中查找部分和完全重复的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 表中查找重复值

在 SQL 表中查找所有相似的行

sql SQL查询使用单个值查找表中的重复项。

在具有重复行的 SQL Server 表中按组查找行号

查找我的 sql 表中可用的日期范围 [重复]

在 SQL 表中查找重复值