Как выполнить SELECT DISTINCT по нескольким столбцам?
Я пытаюсь извлечь все строки из таблицы, где комбинации двух колонок уникальны. То есть мне нужны все продажи, у которых нет других продаж, произошедших в тот же день за ту же цену. Продажи, которые уникальны по дате и цене, должны быть обновлены до статуса "ACTIVE".
Я думаю сделать это следующим образом:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Но я запутался и не знаю, как двигаться дальше. Можете помочь?
4 ответ(ов)
Ваш запрос SELECT DISTINCT a,b,c FROM t
приблизительно эквивалентен:
SELECT a,b,c FROM t GROUP BY a,b,c
Рекомендуется привыкать к синтаксису GROUP BY
, так как он более мощный.
Что касается вашего запроса, я бы написал его следующим образом:
UPDATE sales
SET status='ACTIVE'
WHERE id IN
(
SELECT id
FROM sales S
INNER JOIN
(
SELECT saleprice, saledate
FROM sales
GROUP BY saleprice, saledate
HAVING COUNT(*) = 1
) T
ON S.saleprice=T.saleprice AND S.saledate=T.saledate
)
Таким образом, вы сможете эффективно обновить статусы продаж, основываясь на уникальных значениях цены и даты продажи.
Проблема с вашим запросом заключается в том, что при использовании оператора GROUP BY (что вы фактически делаете, применяя distinct) вы можете использовать только те столбцы, по которым группируете, или агрегатные функции. Вы не можете использовать столбец id, потому что могут быть разные значения. В вашем случае всегда только одно значение из-за оператора HAVING, но большинство СУБД не достаточно умны, чтобы это распознать.
Тем не менее, следующий запрос должен сработать (и не требует объединения):
UPDATE sales
SET status='ACTIVE'
WHERE id IN (
SELECT MIN(id) FROM sales
GROUP BY saleprice, saledate
HAVING COUNT(id) = 1
)
Вы также можете использовать MAX или AVG вместо MIN — главное, чтобы использовалась функция, которая возвращает значение столбца, если существует только одна соответствующая строка.
Если ваша СУБД не поддерживает оператор DISTINCT
для нескольких столбцов, как показано в примере:
SELECT DISTINCT(col1, col2) FROM table
Вы можете выполнить выборку нескольких столбцов безопасно следующим образом:
SELECT DISTINCT * FROM (SELECT col1, col2 FROM table) AS x
Этот подход должен работать в большинстве СУБД и, как правило, будет быстрее, чем использование GROUP BY
, так как вы избегаете функционала группировки.
Для того чтобы получить уникальные значения из колонки GrondOfLucht
в порядке, определенном в колонке sortering
, вы можете использовать оператор GROUP BY
. Ваш текущий запрос возвращает все строки, потому что вы выбираете два столбца (GrondOfLucht
и sortering
), что ведет к дублированию значений. Вместо этого вам необходимо сгруппировать результаты только по GrondOfLucht
, при этом использовать MIN(sortering)
для сортировки. Вот правильный запрос:
SELECT GrondOfLucht
FROM dbo.CorWijzeVanAanleg
GROUP BY GrondOfLucht
ORDER BY MIN(sortering);
В данном запросе:
SELECT GrondOfLucht
— выбираем только уникальные значения из колонкиGrondOfLucht
.FROM dbo.CorWijzeVanAanleg
— указываем таблицу для выборки.GROUP BY GrondOfLucht
— группируем результаты по уникальным значениямGrondOfLucht
, что позволяет избежать дублирования.ORDER BY MIN(sortering)
— сортируем результаты на основании минимального значенияsortering
, что обеспечивает желаемый порядок.
Таким образом, вы получите уникальные значения из GrondOfLucht
, отсортированные по значению из sortering
.
Обновление строк таблицы в Postgres с использованием подзапроса
Как выполнить оператор UPDATE с JOIN в SQL Server?
Обновление данных в одной таблице из другой на основе совпадения ID
Postgres: Как повысить пользователя до суперпользователя?
Как сбросить последовательность первичного ключа в Postgres, когда она потеряла синхронизацию?