2009-11-23 167 views
15

我正在嘗試編寫一個查詢,以從每個唯一設備的GPSReport表中返回最新的GPS位置。表中有50個設備,所以我只需要返回50行。對一列的SELECT DISTINCT,返回多個其他列(SQL Server)

這裏是我到目前爲止(不工作)

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唯一行。它返回第一個設備的所有報告,然後返回第二個設備的所有報告等。

是我在一個查詢中想要做的可能嗎?

+0

給你的數據模式的相關部分可能有助於以後這個驚人的結果。 – Jason 2009-11-23 20:17:05

+0

你在行上有任何唯一的ID嗎? – artdanil 2009-11-23 20:19:18

+0

對不起,該表格包含以下列:device_serial,datetime,triggerID,緯度,經度,速度,地址。 PK由device_serial,datetime,triggerID,緯度,經度列組成。 – mwalsher 2009-11-23 20:32:20

回答

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

如果您只需要設備和時間碼,則只需使用子查詢。 SELECT device_serial,max(datetime)as mostrecent FROM GPSReport group by device_serial – Hogan 2009-11-23 20:24:05

+0

這不太可能,但如果存在多個具有相同datetime和service_serial的記錄,這可能仍會返回重複項。儘管使用分組函數和聚合函數絕對是解決方案。 – MandoMando 2009-11-23 20:26:35

+0

嗯我不這麼認爲,不在sql-server 2005. max只會返回一個值,即使值相同。 (這是max()技巧用於將其他常量字段的列添加到聚合查詢中的原因 – Hogan 2009-11-23 20:34:04

2

你有一個正確的加入,所以如果你有在表GPSReport設備序列號大於1分​​的記錄,它會得到所有的記錄,然後聯合從SELECT DISTINCT device_serial FROM GPSReport收到的唯一列表。

1

嘗試:

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

如何這樣的事情 - 因爲我無法運行它,我希望我的synatx是不完美的

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和日期時間的倍數

1

我會用公用表表達式(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 
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

傑出的,我喜歡它,當答案抽象出細節並展示概念時。 +1 – 2014-06-13 19:41:03

+1

你的答案絕對精彩。非常感謝發佈這個。巨大的幫助。 – joelc 2015-07-27 01:07:09

+0

非常具有描述性。不過,我認爲ORDER BY應該是what_you_want_to_select [DESC]而不是what_you_want_for_distinct。 – verbamour 2016-03-15 19:02:39

0

這是最後的結果不使用不同的,因爲這是新的查詢,其所有有益「SELECT * FROM TBL GROUP BY bandsupported「。其工作同一個鮮明提出並得到所有行

0

我發現正在盡一切的答案在計算器上

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