Удаление похожих столбцов в SQL - PullRequest
1 голос
/ 02 ноября 2009

В PostgreSQL 8.3, скажем, у меня есть таблица с именем widgets со следующим:

 id  | type | count
--------------------
  1  | A    |   21
  2  | A    |   29
  3  | C    |    4
  4  | B    |    1
  5  | C    |    4
  6  | C    |    3
  7  | B    |   14

Я хочу удалить дубликаты на основе столбца type, оставив в таблице только те, которые имеют наибольшее значение столбца count. Окончательные данные будут выглядеть так:

 id  | type | count
--------------------
  2  | A    |   29
  3  | C    |    4  /* `id` for this record might be '5' depending on your query */
  7  | B    |   14

Мне кажется, что я близко, но я не могу обернуться вокруг запроса, который помогает избавиться от дубликатов столбцов.

Ответы [ 3 ]

2 голосов
/ 02 ноября 2009

count является резервным словом sql, так что его придется каким-либо образом экранировать. Я не могу вспомнить синтаксис для этого в Postgres на макушке, поэтому я просто окружил его квадратными скобками (измените его, если это не правильно). В любом случае теоретически должно работать следующее (но я на самом деле не проверял):

delete from widgets where id not in (
select max(w2.id) from widgets as w2 inner join 
(select max(w1.[count]) as [count], type from widgets as w1 group by w1.type) as sq
on sq.[count]=w2.[count] and sq.type=w2.type group by w2.[count]
);
1 голос
/ 02 ноября 2009

Существует несколько более простой ответ, чем у Асафа, с оператором EXISTS SQL:

DELETE FROM widgets AS a 
WHERE EXISTS 
  (SELECT * FROM widgets AS b 
   WHERE (a.type = b.type AND b.count > a.count) 
          OR (b.id > a.id AND a.type = b.type AND b.count = a.count))

Оператор EXISTS возвращает TRUE, если следующий оператор SQL возвращает хотя бы одну запись.

0 голосов
/ 02 ноября 2009

В соответствии с вашими требованиями, мне кажется, что это должно работать:

DELETE 
FROM widgets
WHERE type NOT IN 
(
    SELECT type, MAX(count) 
    FROM widgets 
    GROUP BY type
)
...