SELECT DISTINCT在一列上,返回多个其他列(SQL Server)

时间:2009-11-23 20:12:30

标签: sql sql-server sql-server-2005 tsql

我正在尝试编写一个查询,从每个独特设备的GPSReport表中返回最新的GPS位置。表中有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返回唯一的行。它返回第一个设备的所有报告,然后返回第二个设备的所有报告等。

我正在尝试在一个查询中做什么?

9 个答案:

答案 0 :(得分:26)

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 

答案 1 :(得分: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

答案 2 :(得分:2)

您正在进行正确的加入,因此如果您在表GPSReport中有多个设备序列号记录,则会将所有这些记录和关节记录到从SELECT DISTINCT device_serial FROM GPSReport收到的唯一列表中

答案 3 :(得分:1)

尝试:

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

答案 4 :(得分: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

如果有多个具有相同device_serial和datetime的倍数,您可能需要修改order by子句以选择首选记录

答案 5 :(得分: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

答案 6 :(得分:0)

这是最终结果不使用distinct,因为这是新查询,它对所有“ select * FROM tbl GROUP BY bandsueded ”有帮助。它的工作与另一个提交的工作相同并获得所有行

答案 7 :(得分:0)

在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

答案 8 :(得分:0)

以下内容适用于Postgresql 9 +。

这些答案都不对我有用(不过这是Google为我的搜索返回的第一个链接)。我只需要获取每组行中的第一行,其中给定表达式的计算结果相等,而无需使用任何聚合就丢弃其他行。

This answer向我展示了如何使用DISTINCT ON(与DISTINCT不同):

SELECT DISTINCT ON(x,y) z, k, r, t, v
FROM foo;

在这种情况下,仅采用第一个zz的其余部分将从集合中丢弃。

您只能选择一列(这就是我所做的),而不是示例中的两列。

请记住,由于没有GROUP BY,因此您不能在该查询中使用真实的聚合。

从链接中查看答案以获得更多选项。非常彻底。