Pregunta ¿Cómo usar DISTINCT y ORDER BY en la misma instrucción SELECT?


Después de ejecutar la siguiente declaración:

SELECT  Category  FROM MonitoringJob ORDER BY CreationDate DESC

Obtengo los siguientes valores de la base de datos:

test3
test3
bildung
test4
test3
test2
test1

pero quiero eliminar los duplicados, así:

bildung
test4
test3
test2
test1

Traté de usar DISTINCT pero no funciona con ORDER BY en una declaración. Por favor ayuda.

Importante:

  1. Lo intenté con:

    SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC
    

    no funciona

  2. Ordenar por CreationDate es muy importante.


75
2018-03-22 12:55


origen


Respuestas:


El problema es que las columnas utilizadas en el ORDER BY no están especificados en el DISTINCT. Para hacer esto, necesitas usar un función agregada para ordenar, y usar un GROUP BY hacer el DISTINCT trabajo.

Pruebe algo como esto:

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

132
2018-03-22 13:01



Si no se desea el resultado de MAX (CreationDate), como en el ejemplo de la pregunta original, la única respuesta es la segunda declaración de la respuesta de Prashant Gupta:

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

Explicación: no puede usar la cláusula ORDER BY en una función en línea, por lo que la afirmación en la respuesta de Prutswonder no se puede usar en este caso, no puede poner una selección externa alrededor de ella y descartar la parte MAX (CreationDate).


3
2017-11-30 11:08



Simplemente use este código, si desea valores de columnas de [Categoría] y [Fecha de creación]

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

O use este código, si solo desea valores de la columna [Categoría].

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

Tendrás todos los registros distintos que quieras.


2
2018-01-30 06:46



2) Ordenar por CreationDate es muy importante

Los resultados originales indicaban que "test3" tenía resultados múltiples ...

Es muy fácil comenzar a usar MAX todo el tiempo para eliminar duplicados en Group By ... y olvidar o ignorar cuál es la pregunta subyacente ...

El OP supuestamente se dio cuenta de que el uso de MAX le daba el último "creado" y el uso de MIN daría el primer "creado" ...


1
2017-10-22 10:08



Columnas ampliadas

La razón por la cual lo que quieres hacer no funciona es debido a la orden lógico de operaciones en SQL, que, para su primera consulta, es (simplificado):

  • FROM MonitoringJob
  • SELECT Category, CreationDate es decir, agregar un llamado columna de clave de clasificación extendida
  • ORDER BY CreationDate DESC
  • SELECT Category es decir, eliminar el columna de clave de clasificación extendida de nuevo desde el resultado.

Entonces, gracias al estándar SQL columna de clave de clasificación extendida función, es totalmente posible ordenar por algo que no está en el SELECT cláusula, porque se está añadiendo temporalmente detrás de escena.

Entonces, ¿por qué esto no funciona con DISTINCT?

Si agregamos el DISTINCT operación, se agregaría entre SELECT y ORDER BY:

  • FROM MonitoringJob
  • SELECT Category, CreationDate
  • DISTINCT
  • ORDER BY CreationDate DESC
  • SELECT Category

Pero ahora, con el columna de clave de clasificación extendida  CreationDate, la semántica de la DISTINCT la operación ha cambiado, por lo que el resultado ya no será el mismo. Esto no es lo que queremos, por lo que tanto el estándar SQL como todas las bases de datos razonables prohíben este uso.

Soluciones provisionales

PostgreSQL tiene el DISTINCT ON sintaxis, que puede usarse aquí precisamente para este trabajo:

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

Se puede emular con la sintaxis estándar de la siguiente manera

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

O simplemente, en este caso, como se muestra también en Prutswonder

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

He escrito sobre SQL DISTINCT y ORDER BY más en detalle aquí.


1
2017-07-20 08:24



Distinct clasificará los registros en orden ascendente. Si desea ordenar por orden desc, use:

SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC

Si desea ordenar registros basados ​​en el campo CreationDate, este campo debe estar en la declaración de selección:

SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC

0
2018-03-22 13:10



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

0
2018-01-25 13:59