Postgres удаляет все повторяющиеся записи, кроме одной, путем сортировки - PullRequest
0 голосов
/ 16 октября 2018

Я хотел бы знать, в Postgres, как удалить все повторяющиеся записи, кроме одной, путем сортировки по столбцу.

Допустим, у меня есть следующая таблица foo:

 id                 | name |  region   |          created_at
--------------------+------+-----------+-------------------------------
                  1 | foo  | sydney    | 2018-05-24 15:40:32.593745+10
                  2 | foo  | melbourne | 2018-05-24 17:28:59.452225+10
                  3 | foo  | sydney    | 2018-05-29 22:17:02.927263+10
                  4 | foo  | sydney    | 2018-06-13 16:44:32.703174+10
                  5 | foo  | sydney    | 2018-06-13 16:45:01.324273+10
                  6 | foo  | sydney    | 2018-06-13 17:04:49.487767+10
                  7 | foo  | sydney    | 2018-06-13 17:05:13.592844+10

Я бы хотел удалить все дубликаты, проверив кортеж (имя, регион), но сохранив тот, у которого самый большой столбец created_at.Результат будет:

 id                 | name |  region   |          created_at
--------------------+------+-----------+-------------------------------
                  2 | foo  | melbourne | 2018-05-24 17:28:59.452225+10
                  7 | foo  | sydney    | 2018-06-13 17:05:13.592844+10

Но я не знаю, с чего начать.Есть идеи?

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Используйте подзапрос с ROW_NUMBER и PARTITION BY, чтобы отфильтровать строки с дублирующимися регионами, сохранив при этом самые последние в каждом регионе.Убедитесь, что ваш подзапрос использует ключевое слово AS для предотвращения синтаксических ошибок Postgre:

SELECT * 
FROM foo 
WHERE id IN (
  SELECT a.id 
  FROM (
    SELECT id, ROW_NUMBER() OVER (
        PARTITION BY region 
        ORDER BY created_at DESC
    ) row_no 
    FROM foo
  ) AS a 
  WHERE row_no > 1
);

... возвращает строки, которые будут удалены.Замените SELECT * на DELETE, когда вы будете удовлетворены результатом удаления строк.

SQLFiddle demo

0 голосов
/ 16 октября 2018
DELETE FROM foo
      WHERE id IN
               (SELECT id
                  FROM (SELECT id,
                               ROW_NUMBER ()
                               OVER (PARTITION BY region
                                     ORDER BY created_at DESC)
                                  row_no
                          FROM foo)
                 WHERE row_no > 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...