2009-11-23 45 views
15

Estoy intentando escribir una consulta que devuelva las posiciones de GPS más recientes de una tabla de informe GPS para cada dispositivo único. Hay 50 dispositivos en la tabla, por lo que solo quiero 50 filas devueltas.SELECCIONE DISTINCT en una columna, devuelva varias otras columnas (SQL Server)

Esto es lo que tengo hasta ahora (no funciona)

SELECT TOP(SELECT COUNT(DISTINCT device_serial) FROM GPSReport) * FROM GPSReport AS G1 
RIGHT JOIN 
(SELECT DISTINCT device_serial FROM GPSReport) AS G2 
ON G2.device_serial = G1.device_serial 
ORDER BY G2.device_serial, G1.datetime DESC 

Esto devuelve 50 filas, pero no muestra una fila única para cada device_serial. Devuelve todos los informes para el primer dispositivo, luego todos los informes para el segundo dispositivo, etc.

¿Es lo que intento hacer en una consulta?

+0

Dar las partes relevantes de su esquema de datos podrían ayudar. – Jason

+0

¿tiene alguna identificación única en las filas? – artdanil

+0

Lo sentimos, la tabla tiene las siguientes columnas: device_serial, datetime, triggerID, latitud, longitud, velocidad, dirección. El PK consta de las series device_seal, datetime, triggerID, latitude, longitude. – mwalsher

Respuesta

15
SELECT * FROM 
GPSReport AS G1 
JOIN (SELECT device_serial, max(datetime) as mostrecent 
     FROM GPSReport group by device_serial) AS G2 
ON G2.device_serial = G1.device_serial and g2.mostrecent = g1.datetime 
ORDER BY G1.device_serial 
+0

Si solo necesita el dispositivo y el código de tiempo, puede usar solo la sub consulta. SELECCIONE device_serial, max (datetime) como el más reciente FROM GPSReport group por device_serial – Hogan

+0

Es poco probable, pero esto aún puede devolver los duplicados si hay varios registros con el mismo datetime y service_serial. Sin embargo, el uso de las funciones de agrupar y agrupar definitivamente es la solución. – MandoMando

+0

hmmm No lo creo, no en sql-server 2005. max solo devolverá un valor incluso cuando los valores sean los mismos. (Esta es la razón por la cual el truco max() funciona para agregar en columnas de otros campos constantes a una consulta agregada – Hogan

2

Tiene una unión correcta, por lo que si tiene más de 1 registro para el número de serie del dispositivo en la tabla GPSReport, obtendrá todos los registros y la lista única recibida de SELECT DISTINCT device_serial FROM GPSReport.

1

intento:

Select r.* 
    From GPSReport r 
    Where datetime = 
     (Select Max(DateTime) 
     From GPSReport 
     Where device_serial = r.device_serial) 
1

¿Qué tal algo como esto - ya que no podía ejecutarlo, espero que mi synatx no es perfecto

select * 
    from (
    select device_serial, [datetime], triggerID, latitude, longitude, speed, [address], 
     ROW_NUMBER() over (partition by device_serial order by device_serial asc, [datetime] desc) as row 
     from gpsreport 
) as data 
    where row = 1 

Es posible que tenga que modificar el orden por la cláusula para seleccionar el registro preferido si hay múltiplos con el mismo device_serial y datetime

1

Lo haría con un Expresión común Tabla (CTE), así:

With ResultTable (RowNumber 
       ,device_serial 
       ,datetime 
       ,triggerID 
       ,latitude 
       ,longitude 
       ,speed 
       ,address) 
AS 
(
    SELECT Row_Number() OVER (PARTITION BY device_serial 
            ORDER BY datetime DESC) 
      ,device_serial 
      ,datetime 
      ,triggerID 
      ,latitude 
      ,longitude 
      ,speed 
      ,address 
     FROM GPSReport 
) 
    SELECT device_serial 
      ,datetime 
      ,triggerID 
      ,latitude 
      ,longitude 
      ,speed 
      ,address 
     FROM ResultTable 
    WHERE RowNumber = 1 
22
WITH DEDUPE AS (
    SELECT * 
      , ROW_NUMBER() OVER (PARTITION BY what_you_want_for_distinct ORDER BY what_you_want_for_distinct) AS OCCURENCE 
    FROM tablename 
    ) 
SELECT * FROM DEDUPE 
WHERE 
OCCURENCE = 1 
+2

Excepcional, me encanta cuando las respuestas resumen los detalles y muestran el concepto. +1 –

+1

Su respuesta es absolutamente brillante. Muchas gracias por publicar esto. Gran ayuda – joelc

+0

Muy descriptivo. Sin embargo, creo que el ORDER BY debe ser lo que_se_debe_seleccionar [DESC] en lugar de lo que_se_debe_de_distir. – verbamour

0

Este es el resultado final no utilizan distinta, porque esta es la nueva consulta, su atento para todos "SELECT * FROM GRUPO TBL POR bandsupported ". su labor mismo que uno distinto presentada y obtener todas las filas

0

me encontré con este resultado sorprendente después de probar cada respuesta posible en StackOverflow

WITH cte AS /* Declaring a new table named 'cte' to be a clone of your table */ 
(SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY val1 DESC) AS rn 
    FROM MyTable /* Selecting only unique values based on the "id" field */ 
) 
SELECT * /* Here you can specify several columns to retrieve */ 
FROM cte 
WHERE rn = 1 
Cuestiones relacionadas