【问题标题】:Finding partial and exact duplicate from a SQL table从 SQL 表中查找部分和完全重复
【发布时间】: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
  • 请提供部分和完全重复的定义。
  • 我删除了不准确的数据库标签。请仅使用您真正使用的数据库进行标记。

标签: sql apache-spark-sql


【解决方案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】:
    1. 部分重复 - 使用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
    ----------------------
    
    1. 完全重复 - 您可以使用 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
    ----------------------
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-07
      • 2017-07-05
      • 1970-01-01
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      相关资源
      最近更新 更多