Дополнительно
Как я (или я могу) ВЫБРАТЬ ДИСТИНКТ на нескольких столбцах?
Мне нужно извлечь все строки из таблицы, где 2 столбца объединены. Поэтому я хочу, чтобы все продажи, у которых не было других продаж, произошли в тот же день, по той же цене. Уникальные продажи в зависимости от дня и цены будут обновлены до активного статуса.
Так что я думаю:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Но мой мозг болит, иду дальше, чем это.
382
5
roughly эквивалентно:
Хорошая идея - привыкнуть к синтаксису GROUP BY, так как он более мощный.
Для вашего запроса я бы сделал это так:
Если вы соберете ответы до сих пор, очистите и улучшите, вы получите этот превосходный запрос:
Что намного быстрее, чем у любого из них. Ядерное впечатление от выполнения принятого в настоящее время ответа в 10–15 раз (в моих тестах на PostgreSQL 8.4 и 9.1).
Но это все еще далеко не оптимально. Используйте
НЕ СУЩЕСТВУЕТ
(анти-) полусоединение для еще лучшей производительности. «EXISTS» - это стандартный SQL, он существует вечно (по крайней мере, начиная с PostgreSQL 7.2, задолго до того, как был задан этот вопрос) и идеально соответствует представленным требованиям:Уникальный ключ для идентификации строки
Если у вас нет первичного или уникального ключа для таблицы (
id
в примере), вы можете заменить системный столбецctid
для целей данного запроса (но не для некоторых других целей):Каждая таблица должна иметь первичный ключ. Добавьте один, если у вас его еще не было. Я предлагаю столбец «серийный» или «IDENTITY» в Postgres 10+.& Лт; / sub >
Связанный:
Как это быстрее?
Подрайон в анти-полу-сое
EXISTS
может перестать оценивать, как только будет найден первый дупе (нет смысла смотреть дальше). Для базовой таблицы с несколькими дубликатами это лишь немного эффективнее. С большим количеством дубликатов это становится намного более эффективным.Исключить пустые обновления
Для строк, которые уже имеют
status = 'ACTIVE'
, это обновление ничего не изменит, но все же вставит новую версию строки по полной цене (применяются незначительные исключения). Обычно вы этого не хотите. Добавьте еще одно условие «ГДЕ», как показано выше, чтобы избежать этого и сделать его еще быстрее:Если
status
определенNOT NULL
, вы можете упростить:Тонкая разница в NULL обработке
Этот запрос (в отличие от в настоящее время принятого ответа Джоэла) не рассматривает значения NULL как равные. Следующие два ряда для
(салеприс, саледат)
будут квалифицироваться как «отличительные» (хотя выглядят идентично человеческому глазу):Также проходит уникальный индекс и почти в любом другом месте, поскольку значения NULL не сравниваются равными в соответствии со стандартом SQL. Видеть:
OTOH,
GROUP BY
,DISTINCT
илиDISTINCT ON ()
рассматривают значения NULL как равные. Используйте соответствующий стиль запроса в зависимости от того, чего вы хотите достичь. Вы все еще можете использовать этот более быстрый запрос сНЕ ОТЛИЧАЕТСЯ ОТ
вместо=
для любого или всех сравнений, чтобы сделать NULL равным. Больше:Если все сравниваемые столбцы определены как «НЕ NULL», нет места для разногласий.
[2]: http://sqlfiddle.com/#!17 / 6b5ef / 1
Проблема с вашим запросом заключается в том, что при использовании предложения GROUP BY (которое вы, по сути, делаете, используя отличные), вы можете использовать только столбцы, которые вы группируете, или агрегируете функции. Вы не можете использовать идентификатор столбца, потому что существуют потенциально разные значения. В вашем случае всегда есть только одно значение из-за предложения HAVING, но большинство СУБД недостаточно умны, чтобы распознать это.
Это должно работать однако (и не нуждается в присоединении):
Вы также можете использовать MAX или AVG вместо MIN, важно использовать функцию, которая возвращает значение столбца, если есть только одна совпадающая строка.
Я хочу выбрать отдельные значения из одного столбца «GrondOfLucht», но они должны быть отсортированы в порядке, указанном в столбце «сортировка». Я не могу получить четкие значения только одного столбца, используя
Это также даст столбцу «сортировка», и поскольку «GrondOfLucht» И «сортировка» не уникальны, результатом будут ВСЕ строки.
используйте GROUP, чтобы выбрать записи 'GrondOfLucht' в порядке, указанном 'sortering
Если ваша СУБД не поддерживает различные столбцы, как это:
Multi select в целом можно безопасно выполнить следующим образом:
Поскольку это может работать на большинстве СУБД, ожидается, что это будет быстрее, чем групповое решение, поскольку вы избегаете функциональности группировки.