Вот один вариант, использующий CTE.CTE находит все (match_type, adgroup_id)
группы, имеющие два или более text
значения, которые совпадают с сокращением начальных и конечных пробелов.Мы также вычисляем следующее:
- cnt - для каждой группы, сколько раз появляется «чистая» версия текста.Чистый здесь означает, что текст без начального или конечного пробела
- rn - произвольный номер строки для каждой группы
(match_type, adgroup_id)
, начиная со значения 1
Затем мы удаляем строку только в том случае, если она появляется в дублирующейся группе и либо она не является чистой версией текста (cnt > 0
), либо номер произвольной строки больше единицы.Это означает, что для случаев "Hello "
и " Hello"
одна из этих двух записей будет произвольно удалена.Но если бы существовала третья «чистая» запись с "Hello"
, то она была бы сохранена, и оба из двух предыдущих случаев были бы удалены.
with cte as (
select match_type, adgroup_id, trim(text) as text,
count(case when text = trim(text) then 1 end) as cnt,
row_number() over (partition by match_type, adgroup_id order by trim(text)) rn
from keywords
group by match_type, adgroup_id, trim(text)
having count(*) > 1
)
delete
from keywords k1
where exists (select 1 from cte k2
where k1.match_type = k2.match_type and
k1.adgroup_id = k2.adgroup_id and
k1.text <> k2.text and (k2.cnt > 0 or k2.rn > 1));