SELECT DISTINCT в одном столбце, возвратите несколько других столбцов (SQL Server)

Я пытаюсь написать запрос, который возвращает самые последние позиции GPS из таблицы GPSReport для каждого уникального устройства. В таблице 50 устройств, поэтому мне нужно только вернуть 50 строк.

Вот что я до сих пор (не работает)

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

Это возвращает 50 строк, но не возвращает уникальную строку для каждого device_serial. Он возвращает все отчеты для первого устройства, затем все отчеты для второго устройства и т.д.

Я пытаюсь сделать это в одном запросе?

Ответ 1

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

Ответ 2

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 

Ответ 3

У вас есть правильное соединение, поэтому, если в таблице GPSReport имеется более одной записи для серийного номера устройства, он будет получать все эти записи и совлокальные данные в уникальный список, полученный от SELECT DISTINCT device_serial FROM GPSReport.

Ответ 4

попробовать:

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

Ответ 5

Как насчет чего-то подобного - так как я не мог запустить его, я ожидаю, что мой синтакс не идеален

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

Вам может потребоваться изменить предложение order by, чтобы выбрать предпочтительную запись, если есть кратные с теми же device_serial и datetime

Ответ 6

Я бы сделал это с помощью Common Table Expression (CTE), например:

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

Ответ 7

Это конечный результат, не использующий отдельный, поскольку это новый запрос, его полезный для всех " выберите * FROM tbl GROUP BY bandupported". его работа такая же, как и отдельная, и все строки

Ответ 8

Я нашел этот удивительный результат, попробовав каждый возможный ответ на 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