¿Cómo usar DISTINCT y ORDER BY en la misma instrucción SELECT?
Después de ejecutar la siguiente instrucción:
SELECT Category FROM MonitoringJob ORDER BY CreationDate DESC
Estoy obteniendo los siguientes valores de la base de datos:
test3
test3
bildung
test4
test3
test2
test1
Pero quiero que se eliminen 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:
-
Lo probé con:
SELECT DISTINCT Category FROM MonitoringJob ORDER BY CreationDate DESC
No funciona.
Ordenar por fecha de creación es muy importante.
11 answers
El problema es que las columnas utilizadas en el ORDER BY
no se especifican en el DISTINCT
. Para hacer esto, necesita usar una función aggregate para ordenar, y usar un GROUP BY
para hacer que el DISTINCT
funcione.
Intenta algo como esto:
SELECT DISTINCT Category, MAX(CreationDate)
FROM MonitoringJob
GROUP BY Category
ORDER BY MAX(CreationDate) DESC, Category
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-28 15:48:04
Si la salida de MAX(creationDate) no es deseada - 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 se puede usar la cláusula ORDER BY en una función en línea, por lo que la instrucción en la respuesta de Prutswonder no se puede usar en este caso, no se puede poner una selección externa alrededor de ella y descartar la parte MAX(creationDate).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-16 21:29:37
Simplemente use este código, si desea valores de las columnas [Category] y [creationDate]
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 lo que quieras.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-30 06:46:01
Columnas de clave de ordenación extendidas
La razón por la que lo que quieres hacer no funciona es debido al orden lógico de las operaciones en SQL , que, para tu primera consulta, es (simplificado):
FROM MonitoringJob
-
SELECT Category, CreationDate
es decir, agregar una llamada columna de clave de ordenación extendida ORDER BY CreationDate DESC
-
SELECT Category
es decir, eliminar la columna extended sort key de nuevo del resultado.
Así que, gracias al estándar SQL extended sort key columna característica, es totalmente posible ordenar por algo que no está en la cláusula SELECT
, porque se está agregando temporalmente a ella detrás de las escenas.
Entonces, ¿por qué esto no funciona con DISTINCT
?
Si añadimos la operación DISTINCT
, se añadiría entre SELECT
y ORDER BY
:
FROM MonitoringJob
SELECT Category, CreationDate
DISTINCT
ORDER BY CreationDate DESC
SELECT Category
Pero ahora, con la columna de clave de ordenación extendida CreationDate
, la semántica de la operación DISTINCT
se 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 alternativas
PostgreSQL tiene la sintaxis DISTINCT ON
, que se puede usar aquí precisamente para este trabajo:
SELECT DISTINCT ON (CreationDate) Category
FROM MonitoringJob
ORDER BY CreationDate DESC
Se puede emular con 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 por Prutswonder
SELECT Category, MAX(CreationDate) AS CreationDate
FROM MonitoringJob
GROUP BY Category
ORDER BY CreationDate DESC
Tengo blogueado sobre SQL DISTINTO y ORDEN POR más en detalle aquí .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 08:24:07
2) Ordenar por fecha de creación es muy importante
Los resultados originales indicaban que "test3" tenía múltiples resultados...
Es muy fácil comenzar a usar MAX todo el tiempo para eliminar duplicados en Grupos By... y olvidar o ignorar cuál es la pregunta subyacente...
El OP presumiblemente se dio cuenta de que usar MAX le estaba dando el último "creado" y usar MIN le daría el primer "creado"...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-22 10:08:36
Distinct ordenará los registros en orden ascendente. Si desea ordenar en orden desc utilice:
SELECT DISTINCT Category
FROM MonitoringJob
ORDER BY Category DESC
Si desea ordenar registros basados en el campo creationDate, este campo debe estar en la instrucción select:
SELECT DISTINCT Category, creationDate
FROM MonitoringJob
ORDER BY CreationDate DESC
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-27 11:36:05
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-25 14:11:00
Puedes usar CTE:
WITH DistinctMonitoringJob AS (
SELECT DISTINCT Category Distinct_Category FROM MonitoringJob
)
SELECT Distinct_Category
FROM DistinctMonitoringJob
ORDER BY Distinct_Category DESC
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-10 18:53:38
Pruebe a continuación, pero no es útil para datos enormes...
SELECT DISTINCT Cat FROM (
SELECT Category as Cat FROM MonitoringJob ORDER BY CreationDate DESC
);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-18 13:16:16
Se puede hacer usando una consulta interna Como esta
$query = "SELECT *
FROM (SELECT Category
FROM currency_rates
ORDER BY id DESC) as rows
GROUP BY currency";
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-25 15:35:31
SELECT DISTINCT Category FROM MonitoringJob ORDER BY Category ASC
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-22 12:56:42