我正在尝试从表中删除真正的重复项。我过去多次删除过重复项,但是我无法弄清楚此语法的错误所在。
我的代码-
DELETE
FROM my_table_name
WHERE (
column1, column2, column3, column4, column5, column6, column7, column8, column9) IN
(
SELECT Row_number() OVER( partition BY column1, column2,column3, column4,column5,column6,column7,column8 ORDER BY column2 DESC, column3 ASC ) AS row_num,
column1,
column2,
column3,
column4,
column5,
column6,
column7,
column8,
column9
FROM my_table_name
WHERE column1='some_value') a
WHERE row_num=2;
错误
********** Error **********
ERROR: syntax error at or near ""a""
SQL state: 42601
Character: 1607
我看到错误在于创建别名 a 子查询。但是我无法在这里指出问题所在。
感谢您的帮助
编辑1- 如果删除 a ,则会出现以下错误
********** Error **********
ERROR: syntax error at or near "where"
SQL state: 42601
Character: 1608
答案 0 :(得分:0)
如果有重复的行,则不能只删除一条命令中的一条记录,而是全部删除。您必须删除所有重复项,然后为每个重复行仅插入一个版本,或者构建没有重复项的新表(首选)。
让我们从首选方法开始,该方法是创建一个没有重复项的新表。该解决方案以最有效的方式利用磁盘空间,而不是使用零散的表。
示例:
create table foo
(id int, fname text)
with (appendonly=true)
distributed by (id);
插入一些重复的数据:
insert into foo values (1, 'jon');
insert into foo values (1, 'jon');
insert into foo values (2, 'bill');
insert into foo values (2, 'bill');
insert into foo values (3, 'sue');
insert into foo values (4, 'ted');
insert into foo values (4, 'ted');
insert into foo values (4, 'ted');
insert into foo values (4, 'ted');
创建没有重复表的新版本:
create table foo_new with (appendonly=true) as
select id, fname
from (
select row_number() over (partition by id) as row_num, id, fname
from foo
) as sub
where sub.row_num = 1
distributed by (id);
现在重命名表:
alter table foo rename to foo_old;
alter table foo_new rename to foo;
第二种方法是使用DELETE,但是您将看到它需要完成更多步骤。
首先,使用您要删除的ID创建一个临时表。通常,您在Greenplum中没有强制执行主键,但是您仍然具有逻辑PK。诸如customer_id,product_id等列均在您的数据中。因此,首先要根据PK查找公仔。
drop table if exists foo_pk_delete;
create temporary table foo_pk_delete with (appendonly=true) as
select id
from foo
group by id
having count(*) > 1
distributed by (id);
下一步,为每个重复项获取整行,但只有一个版本。
drop table if exists foo_dedup;
create temporary table foo_dedup with (appendonly=true) as
select id, fname
from (
select row_number() over (partition by f.id) as row_num, f.id, f.fname
from foo f
join foo_pk_delete fd on f.id = fd.id
) as sub
where sub.row_num = 1
distributed by (id);
现在您可以删除重复项:
delete
from foo f
using foo_pk_delete fk
where f.id = fk.id;
然后您可以将重复数据删除的数据重新插入表中。
insert into foo (id, fname)
select id, fname from foo_dedup;
您需要在数据处理后清理表。
vacuum foo;