Как мне (или я могу) 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
Как мне (или я могу) SELECT DISTINCT для нескольких столбцов?
Мы используем файлы cookies для улучшения работы сайта. Оставаясь на нашем сайте, вы соглашаетесь с условиями использования файлов cookies. Чтобы ознакомиться с нашими Положениями о конфиденциальности и об использовании файлов cookie, нажмите здесь.