Redshiftテーブルの重複データを削除しようとしています。
以下は私のクエリです:-
With duplicates
As
(Select *, ROW_NUMBER() Over (PARTITION by record_indicator Order by record_indicator) as Duplicate From table_name)
delete from duplicates
Where Duplicate > 1 ;
このクエリによりエラーが発生します。
Amazonの無効な操作:「delete」またはその近くの構文エラー。
With節の構文が正しいと思われるため、問題が何であるかはわかりません。誰も以前にこの状況に直面したことがありますか?
Redshiftがそのままの状態(どの列にも一意性が強制されない)であるため、Ziggyの3番目のオプションがおそらく最適です。一時テーブルルートに進むと決めたら、全体を入れ替える方が効率的です。 Redshiftでは、削除と挿入は負荷がかかります。
begin;
create table table_name_new as select distinct * from table_name;
alter table table_name rename to table_name_old;
alter table table_name_new rename to table_name;
drop table table_name_old;
commit;
スペースが問題にならない場合は、古いテーブルをしばらく保持し、ここで説明する他の方法を使用して、重複の元のアカウンティングの行数が新しいテーブルの行数と一致することを検証できます。
そのようなテーブルに対して一定のロードを実行している場合、これが進行している間はそのプロセスを一時停止する必要があります。
重複の数が大きなテーブルのわずかな割合である場合、重複の個別のレコードを一時テーブルにコピーしてから、一時と結合するすべてのレコードを元から削除することをお勧めします。次に、 追加 一時テーブルを元に戻します。 vacuum の後に元のテーブルがあることを確認してください(とにかくスケジュールに沿って大きなテーブルに対して行うべきです)。
大量のデータを扱っている場合、テーブル全体を再作成することは常に可能または賢いわけではありません。これらの行を見つけて削除する方が簡単かもしれません:
-- First identify all the rows that are duplicate
CREATE TEMP TABLE duplicate_saleids AS
SELECT saleid
FROM sales
WHERE saledateid BETWEEN 2224 AND 2231
GROUP BY saleid
HAVING COUNT(*) > 1;
-- Extract one copy of all the duplicate rows
CREATE TEMP TABLE new_sales(LIKE sales);
INSERT INTO new_sales
SELECT DISTINCT *
FROM sales
WHERE saledateid BETWEEN 2224 AND 2231
AND saleid IN(
SELECT saleid
FROM duplicate_saleids
);
-- Remove all rows that were duplicated (all copies).
DELETE FROM sales
WHERE saledateid BETWEEN 2224 AND 2231
AND saleid IN(
SELECT saleid
FROM duplicate_saleids
);
-- Insert back in the single copies
INSERT INTO sales
SELECT *
FROM new_sales;
-- Cleanup
DROP TABLE duplicate_saleids;
DROP TABLE new_sales;
COMMIT;
完全な記事: https://elliot.land/post/removing-duplicate-data-in-redshift
うまくいったはずです。あなたができる代替:
With
duplicates As (
Select *, ROW_NUMBER() Over (PARTITION by record_indicator
Order by record_indicator) as Duplicate
From table_name)
delete from table_name
where id in (select id from duplicates Where Duplicate > 1);
または
delete from table_name
where id in (
select id
from (
Select id, ROW_NUMBER() Over (PARTITION by record_indicator
Order by record_indicator) as Duplicate
From table_name) x
Where Duplicate > 1);
主キーがない場合は、次を実行できます。
BEGIN;
CREATE TEMP TABLE mydups ON COMMIT DROP AS
SELECT DISTINCT ON (record_indicator) *
FROM table_name
ORDER BY record_indicator --, other_optional_priority_field DESC
;
DELETE FROM table_name
WHERE record_indicator IN (
SELECT record_indicator FROM mydups);
INSERT INTO table_name SELECT * FROM mydups;
COMMIT;
以下は、重複している 'tablename'のすべてのレコードを削除し、テーブルの重複を削除しません:
DELETE FROM tablename
WHERE id IN (
SELECT id
FROM (
SELECT id,
ROW_NUMBER() OVER (partition BY column1, column2, column3 ORDER BY id) AS rnum
FROM tablename
) t
WHERE t.rnum > 1);
この質問に対する簡単な答え:
row_number=1
。delete
重複したメインテーブルのすべての行。クエリ:
一時テーブル
select id,date into #temp_a from (select *
from (select a.*, row_number() over(partition by id order by etl_createdon desc) as rn from table a where a.id between 59 and 75 and a.date = '2018-05-24') where rn =1)a
メインテーブルからすべての行を削除します。
delete from table a where a.id between 59 and 75 and a.date = '2018-05-24'
すべての値を一時テーブルからメインテーブルに挿入する
insert into table a select * from #temp_a
。
RedshiftはDELETE
句の後のWITH
を許可しないため、クエリは機能しません。許可されるのはSELECT
とUPDATE
および他のいくつかのみです( WITH句 を参照)
ソリューション(私の状況では):
テーブルにid列がありましたevents
には重複する行が含まれており、レコードを一意に識別します。この列id
は、record_indicator
と同じです。
残念ながら、SELECT DISTINCT
を使用して次のエラーが発生したため、一時テーブルを作成できませんでした。
ERROR: Intermediate result row exceeds database block size
しかし、これは魅力のように機能しました:
CREATE TABLE temp as (
SELECT *,ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS rownumber
FROM events
);
temp
テーブルになります:
id | rownumber | ...
----------------
1 | 1 | ...
1 | 2 | ...
2 | 1 | ...
2 | 2 | ...
これで、rownumber
が1より大きい行を削除することで、重複を削除できます。
DELETE FROM temp WHERE rownumber > 1
その後、テーブル名と完了名を変更します。