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

Я работаю над каталогом продуктов (электронная торговля), хранящимся в базе данных 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     ....
...

У меня есть SERIAL PRIMARY KEY в поле ID. У меня есть NOT NULL SKU, NOT NULL код EAN-13 и NOT NULL цена для каждого продукта.

Мы видим, что 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 );

Разве не должно быть Price ASC? Таким образом, самый дешевый будет иметь row_number, равный 1.

The Impaler 08.04.2019 22:46
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
1
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

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

Ответ принят как подходящий

Я бы сделал это, используя коррелированный подзапрос:

delete from mytable t
where t.price > (select min(t2.price) from mytable t2 where t2.sku = t.sku);

Другие вопросы по теме