Удалить дубликаты из таблицы и заново связать ссылки на строки с новым мастером - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть таблица transcription, которая содержит отрывки транскрибированного текста и их цитаты с колонками:

text, transcription_id(PK), t_notes, citation

и вторая таблица town_transcription - это таблица отношений, которая связывает места (из другой таблицы), на которые есть ссылки в тексте, с этой записью транскрипции. Эта таблица имеет столбцы:

town_id(FK), transcription_id(FK), confidence_interval

Многие из этих текстовых отрывков относятся к нескольким городам, но тупо я просто дублировал записи и связывал их индивидуально с каждым городом. Я идентифицировал повторяющиеся строки текста, используя следующий запрос SQL:

SELECT * FROM transcription aa
WHERE (select count(*) from transcription bb
WHERE (bb.text = aa.text) AND (bb.citation = aa.citation)) > 1
ORDER BY text ASC;

Теперь у меня есть около 2000 строк (от 2 до 6 дубликатов некоторых текстовых отрывков), где мне нужно удалить дополнительные transcription_id из таблицы transcription и изменить transcription_id из таблицы отношений, town_transcription, чтобы указать на оставшуюся, теперь уникальную, запись транскрипции. Прочитав другие вопросы, я думаю, что использование UPDATE FROM и INNER JOIN может быть необходимо, но я действительно не знаю, как это реализовать, я только начинающий, спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Эта единственная команда должна делать все это:

WITH blacklist AS (  -- identify duplicate IDs and their master
   SELECT *
   FROM  (
      SELECT transcription_id
           , min(transcription_id) OVER (PARTITION BY text, citation) AS master_id
      FROM   transcription
      ) sub
   WHERE  transcription_id <> master_id
   )
, upd AS (  -- redirect referencing rows
   UPDATE town_transcription tt
   SET    transcription_id = b.master_id
   FROM   blacklist b
   WHERE  b.transcription_id = tt.transcription_id
   )
DELETE FROM transcription t  -- kill dupes (now without reference)
USING  blacklist b
WHERE  b.transcription_id = t.transcription_id;

Из-за отсутствия определения я выбрал строку с наименьшим идентификатором на группу в качестве выживающей главной строки.

Ограничения FK не мешают, если у вас нет нестандартных настроек. Подробное объяснение:

После удаления дубликатов вы можете захотеть добавить ограничение UNIQUE, чтобы предотвратить повторение этой ошибки:

ALTER TABLE transcription
ADD CONSTRAINT transcription_uni UNIQUE (text, citation);
0 голосов
/ 19 ноября 2018

Используйте row_number() over(...) для определения строк, которые повторяют информацию.partition by text, citation в предложении over заставит ряд номеров строк перезапускаться с 1 для каждого уникального набора этих значений:

select
     *
from (
       select
              text, transcription_id, t_notes, citation
            , row_number() over(partition by text, citation 
                                order by transcription_id) as rn
       from transcription 
     ) d
where rn > 1

После того, как вы проверили эти строки как нежелательные, используйтета же логика для оператора удаления.

Однако вы можете потерять информацию, хранящуюся в столбце t_notes - вы готовы это сделать?

...