Как мне (или я могу) SELECT DISTINCT для нескольких столбцов?

Если вы соберете все вместе duplicate ответы, очистите и улучшите, вы sql-update получите следующий превосходный sql запрос:

UPDATE sales
SET    status = 'ACTIVE'
WHERE  (saleprice, saledate) IN (
    SELECT saleprice, saledate
    FROM   sales
    GROUP  BY saleprice, saledate
    HAVING count(*) = 1 
    );

Что намного быстрее, чем pgsql любой из них. Снижает производительность sql принятого в настоящее время sql-query ответа в 10-15 раз (в моих sql-postgres тестах на PostgreSQL 8.4 duplicate-removal и 9.1).

Но это все еще далеко pgsql от оптимального. Используйте postgresql полусоединение NOT EXISTS (анти) для duplicate-removal еще большей производительности. EXISTS - это duplicates стандартный SQL, он существует duplicate всегда (по крайней мере, с duplicate PostgreSQL 7.2, задолго до database-update того, как был задан этот distinct вопрос) и идеально соответствует sql-postgres представленным требованиям:

UPDATE sales s
SET    status = 'ACTIVE'
WHERE  NOT EXISTS (
   SELECT FROM sales s1                     -- SELECT list can be empty for EXISTS
   WHERE  s.saleprice = s1.saleprice
   AND    s.saledate  = s1.saledate
   AND    s.id <> s1.id                     -- except for row itself
   )
AND    s.status IS DISTINCT FROM 'ACTIVE';  -- avoid empty updates. see below

db <> скрипка here
Old SQL Fiddle

Уникальный ключ для идентификации строки

Если distinct у вас нет первичного или duplicates уникального ключа для таблицы sql-query (id в примере), вы можете заменить duplicates его системным столбцом ctid для sql-update целей этого запроса (но не sql-update для некоторых других целей) :

   AND    s1.ctid <> s.ctid

Каждая таблица должна иметь первичный ключ. Добавьте еще, если у вас его еще не было. Я предлагаю столбец serial или IDENTITY в Postgres 10+.

Связанные:

Как это быстрее?

Подзапрос sql-postgres в анти-полусоединении EXISTS может sql-query перестать оцениваться, как sql-select только будет обнаружен первый sql-syntax обман (нет смысла искать duplicate-removal дальше). Для базовой таблицы sql-update с несколькими дубликатами sql-syntax это лишь немного эффективнее. При distinct большом количестве дубликатов sql это становится способом более эффективным

.

Исключить пустые обновления

Для sql-query строк, в которых уже есть distinct status = 'ACTIVE', это обновление ничего не database-update изменит, но все равно вставит postgres новую версию строки за полную postgresql стоимость (возможны незначительные sql-postgres исключения). Обычно вы этого sql-query не хотите. Добавьте еще одно duplicate условие WHERE, как показано выше, чтобы sql-syntax избежать этого и сделать database-update его еще быстрее:

Если status определен database-update как NOT NULL, вы можете упростить pgsql до:

AND status <> 'ACTIVE';

Тип данных столбца должен postgres поддерживать оператор <>. Некоторые pgsql типы, такие как json, этого не sql-syntax делают. См .:

Тонкая разница в обработке NULL

Этот запрос sql-query (в отличие от currently accepted answer by Joel) не обрабатывает pgsql значения NULL как равные. Следующие duplicate две строки для (saleprice, saledate) будут квалифицированы duplicates как "отдельные" (хотя sql-update выглядят идентично человеческому sql-query глазу):

(123, NULL)
(123, NULL)

Также передается уникальный sql-postgres индекс и почти везде, поскольку pgsql значения NULL не равны в pgsql соответствии со стандартом sql-query SQL. См .:

OTOH, GROUP BY, DISTINCT или DISTINCT ON () обрабатывают distinct значения NULL как равные. Используйте pgsql соответствующий стиль запроса postgresql в зависимости от того, чего database-update вы хотите достичь. Вы по-прежнему duplicates можете использовать этот pgsql более быстрый запрос с IS NOT DISTINCT FROM вместо distinct = для любого или всех сравнений, чтобы sql-update сделать сравнение NULL равным. Подробнее:

Если sql-update все сравниваемые столбцы distinct определены NOT NULL, нет места разногласиям.

sql

postgresql

sql-update

duplicates

distinct

2022-11-13T13:54:40+00:00
Вопросы с похожей тематикой, как у вопроса:

Как мне (или я могу) SELECT DISTINCT для нескольких столбцов?