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)
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)
当然,您会留下一个新表和松散的表历史记录、主键、外键等。
| 归档时间: |
|
| 查看次数: |
38558 次 |
| 最近记录: |