Удалите дубликаты, сохранив только самую низкую цену

Я работаю над каталогом продуктов (электронная торговля), хранящимся в базе данных PostgreSQL. У меня есть дубликаты. Я хочу удалить эти повторяющиеся товары, оставив только самый дешевый.

Важные поля в базе данных:

ID [PK]   SKU   EAN    Price    ....
1         SKU1  123    45.0     ....
2         SKU2  456    36.0     ....
3         SKU3  123    40.0     ....
4         SKU4  789    58.0     ....
5         SKU5  123    38.0     ....
...

У меня есть СЕРИЙНЫЙ ПЕРВИЧНЫЙ КЛЮЧ на поле ID. У меня НЕ ПУСТОЙ SKU, НЕ ПУСТОЙ код EAN-13 и НЕ НУЛЕВАЯ цена для каждого продукта.

Мы видим, что EAN «123» дублируется несколько раз. Я хотел бы найти запрос SQL, который удаляет все дубликаты (всю строку), оставив только ОДИН, который будет иметь самую низкую цену.

Мы бы хотели иметь :

ID [PK]   SKU   EAN    Price    ....
2         SKU2  456    36.0     ....
4         SKU4  789    58.0     ....
5         SKU5  123    38.0     ....
...

Чтобы знать: количество дубликатов может быть переменным. Вот пример с 3 продуктами с одинаковым EAN, но у нас может быть 2, 4, 8 или 587 ...

Пока мне удалось удалить дубликат с наименьшим или наибольшим идентификатором только в случае двух дубликатов, но это не то, что я пытаюсь найти ...

    FROM 
        (SELECT Price,
         MIN(Price) OVER( PARTITION BY ean ORDER BY  Price DESC ) AS row_num FROM TABLE ) t
        WHERE t.row_num > 1 );

person IndiaSke    schedule 08.04.2019    source источник
comment
Разве это не должно быть Price ASC? Таким образом, самый дешевый будет иметь row_number равный 1.   -  person The Impaler    schedule 08.04.2019


Ответы (2)


Я бы сделал это с помощью коррелированного подзапроса:

delete from mytable t
where t.price > (select min(t2.price) from mytable t2 where t2.sku = t.sku);
person Gordon Linoff    schedule 08.04.2019

Вот одно решение, использующее синтаксис Postgres DELETE ... USING:

DELETE 
FROM mytable t1
USING mytable t2
WHERE t1.sku = t2.sku AND t1.price > t2.price

Это удалит записи с повторяющимися sku, но сохранит запись с наименьшим price.

person GMB    schedule 08.04.2019