Как использовать 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. Я попытался это:

    SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC
    

    он не работает.

  2. порядок Дата создания-это очень важно.

11 80

11 ответов:

проблема в том, что столбцы, используемые в ORDER BY не указаны в DISTINCT. Для этого вам нужно использовать агрегатная функция для сортировки и использования GROUP BY сделать DISTINCT работа.

попробуйте что-то вроде этого:

SELECT DISTINCT Category, MAX(CreationDate) 
FROM MonitoringJob 
GROUP BY Category 
ORDER BY MAX(CreationDate) DESC, Category

Если вывод MAX (CreationDate) не требуется - как в Примере исходного вопроса - единственным ответом является второе утверждение ответа Прашанта Гупты:

SELECT [Category] FROM [MonitoringJob] 
GROUP BY [Category] ORDER BY MAX([CreationDate]) DESC

пояснение: вы не можете использовать предложение ORDER BY во встроенной функции, поэтому оператор в ответе Prutswonder не может использоваться в этом случае, вы не можете поместить внешний выбор вокруг него и отбросить часть MAX(CreationDate).

просто используйте этот код, Если вы хотите значения столбцов [Category] и [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

вы будете иметь все различные записи, что когда-либо вы хотите.

Расширенная сортировка ключевых столбцов

причина, что вы хотите сделать, не работает из-за логический порядок операций в 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, и все разумные базы данных запрещают это использование.

решения

PostgreSQL имеет DISTINCT ON синтаксис, который может быть использован здесь именно для этой работы:

SELECT DISTINCT ON (CreationDate) Category 
FROM MonitoringJob 
ORDER BY CreationDate DESC

он может быть эмулирован со стандартным синтаксисом следующим образом

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 более подробно здесь.

2) Порядок создания-это очень важно

исходные результаты показали, что" test3 " имел несколько результатов...

очень легко начать использовать MAX все время, чтобы удалить дубликаты в Group By... и забыть или игнорировать то, что лежит в основе вопроса...

OP предположительно понял, что использование MAX дает ему последнее "созданное", а использование MIN даст первое "созданное"...

Distinct будет сортировать записи в порядке возрастания. Если вы хотите сортировать в порядке desc, используйте:

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

Если вы хотите сортировать записи на основе поля CreationDate, то это поле должно быть в инструкции select:

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC
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

вы можете использовать CTE:

WITH DistinctMonitoringJob AS (
    SELECT DISTINCT Category Distinct_Category FROM MonitoringJob 
)

SELECT Distinct_Category 
FROM DistinctMonitoringJob 
ORDER BY Distinct_Category DESC

попробуйте дальше, но это не полезно для огромных данных...

SELECT DISTINCT Cat FROM (
  SELECT Category as Cat FROM MonitoringJob ORDER BY CreationDate DESC
);

Это можно сделать с помощью внутреннего запроса, как это

$query = "SELECT * 
            FROM (SELECT Category  
                FROM currency_rates                 
                ORDER BY id DESC) as rows               
            GROUP BY currency";
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC