J'essaie de supprimer des données en double dans ma table redshift.
Ci-dessous ma requête: -
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 ;
Cette requête me donne une erreur.
Opération Amazon non valide: erreur de syntaxe proche de "delete";
Je ne sais pas quel est le problème, car la syntaxe de la clause with semble être correcte… Est-ce que quelqu'un a déjà affronté cette situation?
Redshift étant ce qu’il est (pas d’unicité imposée pour une colonne), la 3ème option de Ziggy est probablement la meilleure. Une fois que nous décidons d’utiliser la table de travail temporaire, il est plus efficace d’échanger des éléments entiers. Les suppressions et les insertions sont coûteuses dans 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;
Si l'espace n'est pas un problème, vous pouvez conserver l'ancienne table pendant un certain temps et utiliser les autres méthodes décrites ici pour valider que le nombre de lignes dans la comptabilisation d'origine des doublons correspond au nombre de lignes du nouveau.
Si vous chargez constamment une telle table, vous voudrez mettre ce processus en pause.
Si le nombre de doublons représente un faible pourcentage d'une table volumineuse, vous pouvez essayer de copier des enregistrements distincts des doublons dans une table temporaire, puis supprimer tous les enregistrements de l'original qui se joignent au fichier temporaire. Puis annexer la table temporaire à l’original. Assurez-vous de vider la table d'origine après (ce que vous devriez faire de toute façon pour les tables volumineuses).
Si vous traitez beaucoup de données, il n'est pas toujours possible ni intelligent de recréer la table entière. Il peut être plus facile de localiser, supprimer ces lignes:
-- 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;
Article complet: https://elliot.land/post/removing-duplicate-data-in-redshift
Ce qui suit supprime tous les enregistrements de 'nomtable' qui ont un doublon, il ne dédupliquera pas la table:
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);
Cela aurait dû fonctionner. Alternative que vous pouvez faire:
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);
ou
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);
Si vous n'avez pas de clé primaire, vous pouvez effectuer les opérations suivantes:
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;
Réponse simple à cette question:
row_number=1
.delete
toutes les lignes de la table principale sur lesquelles nous avons eu des doublons.Requêtes:
Table temporaire
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
supprimer toutes les lignes de la table principale.
delete from table a
where a.id between 59 and 75 and a.date = '2018-05-24'
insérer toutes les valeurs de la table temporaire dans la table principale
insert into table a select * from #temp_a
.
Votre requête ne fonctionne pas car Redshift n'autorise pas DELETE
après la clause WITH
. Seuls SELECT
et UPDATE
et quelques autres sont autorisés (voir WITH clause )
Solution (dans ma situation):
Ma table events
contenait une colonne id contenant des lignes en double et identifiant de manière unique l’enregistrement. Cette colonne id
est identique à votre record_indicator
.
Malheureusement, je n'ai pas pu créer de table temporaire car j'ai rencontré l'erreur suivante avec SELECT DISTINCT
:
ERROR: Intermediate result row exceeds database block size
Mais cela a fonctionné comme un charme:
CREATE TABLE temp as (
SELECT *,ROW_NUMBER() OVER (PARTITION BY id ORDER BY id) AS rownumber
FROM events
);
résultant dans la table temp
:
id | rownumber | ...
----------------
1 | 1 | ...
1 | 2 | ...
2 | 1 | ...
2 | 2 | ...
Vous pouvez maintenant supprimer les doublons en supprimant les lignes dont la variable rownumber
est supérieure à 1:
DELETE FROM temp WHERE rownumber > 1
Après cela, renommez les tables et vous avez terminé.