【问题标题】:Unable to delete duplicate data from Netezza table无法从 Netezza 表中删除重复数据
【发布时间】:2018-01-10 08:25:27
【问题描述】:

我正在尝试从 netezza 表中删除重复记录。但是很少有列包含空值,所以下面的代码不起作用。

DELETE FROM TABLE_NAME a
     WHERE ROW_NUMBER() <> ( SELECT MIN( ROW_NUMBER() )
                               FROM TABLE_NAME b
                              WHERE a.COL1  = b.COL1
                                AND a.COL2  = b.COL2
                                AND a.COL3  = b.COL3);

Sample Data:-
COL1  COL2  COL3
X     NULL     Y
A     NULL     B
X     NULL     Y
X     NULL     Y
E     VAL      F

Expected result:
    COL1  COL2  COL3
    X     NULL     Y
    A     NULL     B
    E     VAL      F

注意:COL2 列包含空值。 我们在这个表中总共有 30 列,其中 6 列包含重复记录的空值。

谁能帮我解决这个问题。

【问题讨论】:

  • 更新您的问题添加适当的数据样本和预期结果

标签: sql netezza aginity


【解决方案1】:
DELETE FROM TABLE_NAME a
     WHERE ROW_NUMBER() <> ( SELECT MIN( ROW_NUMBER() )
                               FROM TABLE_NAME b
                              WHERE nvl(a.COL1,0)  = nvl(b.COL1,0)
                                AND nvl(a.COL2,0)  = nvl(b.COL2,0)
                               and nvl(a.COL3,0)  = nvl(b.COL3,0));

使用 NVL 函数将空值替换为 0

【讨论】:

  • nvl 不工作.. 错误 [HY000] 错误:(2) 不支持这种形式的相关查询 - 考虑重写
【解决方案2】:

您可以使用NVL 函数将空值转换为可以比较的值。 *编辑:您评论说 NVL 不起作用。或者,您可以重写查询以显式处理 NULL:

例如:

DELETE FROM TABLE_NAME a
     WHERE ROW_NUMBER() <> ( SELECT MIN( ROW_NUMBER() )
                               FROM TABLE_NAME b
                              WHERE((a.COL1 = b.COL1) or (a.COL1 is null and b.COL1 is null))
                                AND ((a.COL2 = b.COL2) or (a.COL2 is null and b.COL2 is null))
                                AND ((a.COL3 = b.COL3) or (a.COL3 is null and b.COL3 is null));

【讨论】:

  • nvl 不工作.. 错误 [HY000] 错误:(2) 不支持这种形式的相关查询 - 考虑重写
  • 如果没有处理空值的更改,DELETE 是否工作?我不知道 Netezza,但它似乎对子查询有很大的限制......
  • 是的,删除查询语法是正确的。但由于 null 值,它不能删除任何记录。所以输出是“0 条记录受影响”。
【解决方案3】:

尝试使用 /=/ 运算符而不是 = 在这些情况下它通常对我有用

【讨论】:

    【解决方案4】:

    关于上下文,表的分布列是什么,表中有多少行,以及您预计其中有多少行是重复的?根据规模,CTA​​S 方法可能比 DELETE 更适合。

    话虽如此,这是一种正确删除逻辑的方法,但可能不是表现最好的。

    TESTDB.ADMIN(ADMIN)=> select * from table_name;
     COL1 | COL2 | COL3 
    ------+------+------
     X    |      | Y
     X    |      | Y
     E    | VAL  | F
     A    |      | B
     X    |      | Y
    (5 rows)
    
    delete 
    from 
            table_name
    where   rowid in 
            ( select 
                    rowid 
            from 
                    ( select 
                            rowid, 
                            row_number() over (
                                       partition by col1, 
                                               col2     , 
                                               col3 
                                       order by 
                                               col1) rn
                    from 
                            table_name
                    ) foo
            where   rn > 1
            ) ;
    
    DELETE 2
    TESTDB.ADMIN(ADMIN)=> select * from table_name;
     COL1 | COL2 | COL3 
    ------+------+------
     A    |      | B
     X    |      | Y
     E    | VAL  | F
    (3 rows)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-13
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 2019-11-02
      相关资源
      最近更新 更多