RedShift — Как фильтровать записи в таблице по составному первичному ключу?

#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
                 );