如何删除Snowflake数据库表中的重复记录

Vik*_*iki 17 snowflake-cloud-data-platform

如何从雪花表中删除重复记录?

ID Name
1  Apple
1  Apple
2  Apple
3  Orange
3  Orange
Run Code Online (Sandbox Code Playgroud)

结果应该是:

ID Name
1  Apple
2  Apple
3  Orange
Run Code Online (Sandbox Code Playgroud)

Fel*_*ffa 31

此处添加一个不重新创建表的解决方案。这是因为重新创建表可能会破坏许多现有配置和历史记录。

相反,我们将在事务中仅删除重复的行并插入每个行的单个副本:


-- find all duplicates
create or replace transient table duplicate_holder as (
    select $1, $2, $3
    from some_table
    group by 1,2,3
    having count(*)>1
);

-- time to use a transaction to insert and delete
begin transaction;

-- delete duplicates
delete from some_table a
using duplicate_holder b
where (a.$1,a.$2,a.$3)=(b.$1,b.$2,b.$3);

-- insert single copy
insert into some_table
select * 
from duplicate_holder;

-- we are done
commit;
Run Code Online (Sandbox Code Playgroud)

优点:

  • 不重新创建表
  • 不修改原表
  • 仅删除和插入重复的行(有利于时间旅行存储成本,避免不必要的重新聚集)
  • 一切尽在一笔交易中


Tob*_*yLL 21

这是一个非常简单的方法,不需要任何临时表。它对于小表来说非常有效,但对于大表来说可能不是最好的方法。

insert overwrite into some_table
select distinct * from some_table
;
Run Code Online (Sandbox Code Playgroud)

OVERWRITE关键字意味着表将在插入之前被截断。


Sim*_*rim 13

如果您有这样的主键:

CREATE TABLE fruit (key number, id number, name text);

insert into fruit values (1,1, 'Apple'), (2,1,'Apple'),
      (3,2, 'Apple'), (4,3, 'Orange'), (5,3, 'Orange');
Run Code Online (Sandbox Code Playgroud)

就像那时一样

DELETE FROM fruit
WHERE key in (
  SELECT key 
  FROM (
      SELECT key
          ,ROW_NUMBER() OVER (PARTITION BY id, name ORDER BY key) AS rn
      FROM fruit
  )
  WHERE rn > 1
);
Run Code Online (Sandbox Code Playgroud)

但如果您没有唯一密钥,则无法以这种方式删除。此时一个

CREATE TABLE new_table_name AS
SELECT id, name FROM (
    SELECT id
        ,name
        ,ROW_NUMBER() OVER (PARTITION BY id, name) AS rn
    FROM table_name
)
WHERE rn > 1
Run Code Online (Sandbox Code Playgroud)

然后交换它们

ALTER TABLE table_name SWAP WITH new_table_name
Run Code Online (Sandbox Code Playgroud)


Han*_*sen 7

Snowflake 没有有效的主键,它们的使用主要与 ERD 工具一起使用。Snowflake 也没有 ROWID 之类的东西,因此无法识别要删除的重复项。

可以临时添加“is_duplicate”列,例如。使用 ROW_NUMBER() 函数对所有重复项进行编号,然后删除所有“is_duplicate”> 1 的记录,最后删除实用程序列。

另一种方法是创建一个重复的表并交换,正如其他人所建议的那样。然而,必须保留限制和补助。一种方法是:

CREATE TABLE new_table LIKE old_table COPY GRANTS;
INSERT INTO new_table SELECT DISTINCT * FROM old_table;
ALTER TABLE old_table SWAP WITH new_table;
Run Code Online (Sandbox Code Playgroud)

上面的代码删除了精确的重复项。如果您想为每个“PK”添加一行,则需要包含逻辑来选择要保留的副本

这说明了在雪花数据仓库中添加更新时间戳列的重要性。


小智 7

这也困扰了我一段时间。由于 Snowflake 添加了对限定的支持,您现在可以使用单个语句创建一个不带子选择的重复数据删除表:

CREATE TABLE fruit (id number, nam text);
insert into fruit values (1, 'Apple'), (1,'Apple'),
      (2, 'Apple'), (3, 'Orange'), (3, 'Orange');


CREATE OR REPLACE TABLE fruit AS 
SELECT * FROM 
fruit 
qualify row_number() OVER (PARTITION BY id, nam ORDER BY id, nam) = 1;
SELECT * FROM fruit;
Run Code Online (Sandbox Code Playgroud)

当然,您会留下一个新表和松散的表历史记录、主键、外键等。