Как использовать DISTINCT и ORDER BY в одном выражении SELECT?
После выполнения следующего оператора:
SELECT Category FROM MonitoringJob ORDER BY CreationDate DESC
Я получаю следующие значения из базы данных:
test3
test3
bildung
test4
test3
test2
test1
но я хочу, чтобы дубликаты были удалены, например:
bildung
test4
test3
test2
test1
Я попытался использовать DISTINCT, но он не работает с ORDER BY в одном выражении. Пожалуйста, помогите.
Важно:
Ответы
Ответ 1
Проблема в том, что столбцы, используемые в ORDER BY
, не указаны в DISTINCT
. Чтобы сделать это, вам нужно использовать агрегатную функцию для сортировки и использовать GROUP BY
чтобы заставить DISTINCT
работать.
Попробуйте что-то вроде этого:
SELECT DISTINCT Category, MAX(CreationDate)
FROM MonitoringJob
GROUP BY Category
ORDER BY MAX(CreationDate) DESC, Category
Ответ 2
Расширенные столбцы ключей сортировки
Причина, по которой вы не хотите работать, заключается в логическом порядке операций в SQL, который для вашего первого запроса (упрощен):
-
FROM MonitoringJob
-
SELECT Category, CreationDate
т.е. добавить так называемый расширенный столбец ключа сортировки -
ORDER BY CreationDate DESC
-
SELECT Category
т.е. снова удалите расширенный столбец ключа сортировки из результата.
Таким образом, благодаря стандартной функции расширенного столбца ключа сортировки SQL, можно полностью упорядочить что-то, чего нет в предложении SELECT
, потому что оно временно добавляется к нему за кулисами.
Итак, почему это не работает с DISTINCT
?
Если мы добавим операцию DISTINCT
, она будет добавлена между SELECT
и ORDER BY
:
-
FROM MonitoringJob
-
SELECT Category, CreationDate
-
DISTINCT
-
ORDER BY CreationDate DESC
-
SELECT Category
Но теперь, с расширенным столбцом ключа сортировки CreationDate
, семантика операции DISTINCT
была изменена, поэтому результат больше не будет прежним. Это не то, что мы хотим, поэтому и стандарт SQL, и все разумные базы данных запрещают это использование.
обходные
Его можно эмулировать со стандартным синтаксисом следующим образом
SELECT Category
FROM (
SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
) t
ORDER BY CreationDate DESC
Или просто (в данном случае), как показано Prutswonder
SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
ORDER BY CreationDate DESC
Я более подробно писал о SQL DISTINCT и ORDER BY здесь.
Ответ 3
Если вывод MAX (CreationDate) не нужен - как в примере исходного вопроса - единственный ответ - это второй оператор ответа Прашанта Гупта:
SELECT [Category] FROM [MonitoringJob]
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC
Объяснение: вы не можете использовать предложение ORDER BY в встроенной функции, поэтому утверждение в ответе Prutswonder в этом случае невозможно использовать, вы не можете поместить внешний выбор вокруг него и отменить MAX (CreationDate ) часть.
Ответ 4
Просто используйте этот код. Если вам нужны значения столбцов [Категория] и [CreationDate]
SELECT [Category], MAX([CreationDate]) FROM [MonitoringJob]
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC
Или используйте этот код, если вы хотите только значения столбца [Категория].
SELECT [Category] FROM [MonitoringJob]
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC
У вас будут все записи, которые вы хотите.
Ответ 5
2) Заказ by CreationDate очень важен
Исходные результаты показали, что "test3" имеет несколько результатов...
Очень легко начать использовать MAX все время, чтобы удалить дубликаты в Group By... и забыть или игнорировать то, что основной вопрос...
OP предположительно осознал, что использование MAX дало ему последний "созданный", и использование MIN дало бы первый "созданный"...
Ответ 6
if object_id ('tempdb..#tempreport') is not null
begin
drop table #tempreport
end
create table #tempreport (
Category nvarchar(510),
CreationDate smallint )
insert into #tempreport
select distinct Category from MonitoringJob (nolock)
select * from #tempreport ORDER BY CreationDate DESC
Ответ 7
По подзапросу должно работать:
SELECT distinct(Category) from MonitoringJob where Category in(select Category from MonitoringJob order by CreationDate desc);
Ответ 8
Distinct будет сортировать записи в порядке возрастания. Если вы хотите отсортировать в порядке desc, используйте:
SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC
Если вы хотите отсортировать записи на основе поля CreationDate, это поле должно быть в инструкции select:
SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC
Ответ 9
Вы можете использовать CTE:
WITH DistinctMonitoringJob AS (
SELECT DISTINCT Category Distinct_Category FROM MonitoringJob
)
SELECT Distinct_Category
FROM DistinctMonitoringJob
ORDER BY Distinct_Category DESC
Ответ 10
Попробуйте следующее, но это не полезно для огромных данных...
SELECT DISTINCT Cat FROM (
SELECT Category as Cat FROM MonitoringJob ORDER BY CreationDate DESC
);
Ответ 11
Это можно сделать, используя внутренний запрос. Как этот
$query = "SELECT *
FROM (SELECT Category
FROM currency_rates
ORDER BY id DESC) as rows
GROUP BY currency";
Ответ 12
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC