web-dev-qa-db-fra.com

SELECT DISTINCT sur une colonne, retourne plusieurs autres colonnes (SQL Server)

J'essaie d'écrire une requête qui renvoie les positions GPS les plus récentes à partir d'une table GPSReport pour chaque périphérique unique. Il y a 50 périphériques dans la table, je ne souhaite donc que 50 lignes renvoyées.

Voici ce que j'ai jusqu'à présent (ne fonctionne pas)

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

Cela retourne 50 lignes, mais ne renvoie pas une ligne unique pour chaque périphérique_serial. Il renvoie tous les rapports du premier périphérique, puis tous les rapports du deuxième périphérique, etc.

Est-ce que ce que j'essaie de faire est possible en une requête?

17
mwalsher
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
15
Hogan
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 
24
Howie

Vous avez une jointure correcte. Par conséquent, si vous avez plus d'un enregistrement pour le numéro de série du périphérique dans la table GPSReport, tous ces enregistrements seront joints à la liste unique reçue de SELECT DISTINCT device_serial FROM GPSReport.

2
artdanil

essayer:

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

Je le ferais avec une expression de table commune (CTE), comme ceci:

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
1
Bliek

Que diriez-vous de quelque chose comme ça - comme je ne pouvais pas l'exécuter, je m'attends à ce que mon synatx ne soit pas parfait

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

Vous devrez peut-être modifier la clause order by pour sélectionner l'enregistrement préféré s'il existe des multiples avec les mêmes device_serial et datetime.

1
Ray

Ceci est le résultat final, n'utilisez pas distinct, car il s'agit de la nouvelle requête, son aide pour tous " select * FROM tbl GROUP BY bandsupported ". son travail est le même que celui distinct classé et obtenir toutes les lignes

0
Sourav Kundu

J'ai trouvé ce résultat incroyable après avoir essayé toutes les réponses possibles sur 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
0
mn128b