#sql #amazon-redshift
#sql #amazon-redshift
Вопрос:
Я пишу скрипт для удаления дубликатов в таблице RedShift. Но поскольку таблица имеет составной первичный ключ, содержащий 2 столбца, я столкнулся с проблемой при выборе и фильтрации значений.
Вот что я реализовал до сих пор. Было бы легко, если бы у меня был только один столбец в качестве PK, но как добиться того же результата для составного ключа ( sale_id, sale_date
)? Особенно проблематичным является второй шаг — копирование отдельных строк с условием WHERE для составного ключа в новую таблицу.
Шаг 1
-- Saving PKs with dupes into a TEMP TABLE
CREATE TEMP TABLE main.duplicate_sales AS
SELECT sale_id, sale_date
FROM main.sales
WHERE sale_date=2019-05-20
GROUP BY 1,2
HAVING COUNT(*) > 1;
Шаг 2
-- Copy distinct rows for the above PKs to a new table
CREATE TEMP TABLE main.sales_new(LIKE main.sales);
INSERT INTO main.sales_new
SELECT DISTINCT *
FROM main.sales
WHERE sale_id, sale_date IN(
SELECT sale_id, sale_date
FROM main.duplicate_sales
);
UPD: таблица очень большая, поэтому я хочу избежать выбора всех записей. После копирования отдельных записей в новую таблицу (шаг 2) Я удаляю повторяющиеся строки из исходной таблицы (шаг 3), а затем вставляю отдельные записи из новой таблицы (шаг 4).
Шаг 3
-- Delete all rows that contain duplicates
DELETE FROM main.sales
WHERE sale_id, sale_date IN(
SELECT sale_id, sale_date
FROM main.duplicate_sales
);
Шаг 4
-- Insert back distinct records
INSERT INTO main.sales
SELECT *
FROM main.sales_new;
Комментарии:
1. не могли бы вы поделиться своими примерами данных
2. Я в замешательстве. Если два столбца являются первичным ключом, то они уникальны. Вы хотите сказать, что у вас есть два столбца, которые вы хотите сделать уникальными, но это не так?
3. @GordonLinoff PK в RedShift не гарантируют отсутствие повторяющихся записей. Мне просто нужно очистить исторические данные
Ответ №1:
как насчет того, чтобы просто взять отдельное значение sale_id, sale_date
create table table_name_new as select distinct sale_id, sale_date
from main.sales;
Ответ №2:
Я довольно смущен вашим вопросом и тем, что происходит с остальными столбцами. Однако EXISTS
может быть достаточно заменить ваш текущий второй шаг:
INSERT INTO main.sales_new
SELECT DISTINCT s.*
FROM main.sales s
WHERE EXISTS (SELECT 1
FROM main.duplicate_sales ds
WHERE ds.sale_id = s.sale_id AND
ds.sale_date = s.sale_date
);