使用SQL根据两行的最大值选择唯一记录

时间:2016-05-24 15:10:08

标签: mysql sql

我有一个表格,用于存储设备ID,消息,日期和时间。

我能够毫无问题地查询并获取所有记录,但是,我想要做的是从每个设备获取最新消息。例如,我的数据库看起来像:

device id     msg             date           time
Device 0 -- Message 0 -- 2016 - 05 - 22 -- 08:00:00
Device 1 -- Message 1 -- 2016 - 05 - 22 -- 09:00:00
Device 0 -- Message 2 -- 2016 - 05 - 23 -- 10:00:00
Device 1 -- Message 3 -- 2016 - 05 - 23 -- 11:00:00
Device 0 -- Message 4 -- 2016 - 05 - 24 -- 17:00:00
Device 1 -- Message 5 -- 2016 - 05 - 24 -- 16:00:00

我希望结果是:

Device 0 -- Message 4 -- 2016 - 05 - 24 -- 17:00:00
Device 1 -- Message 5 -- 2016 - 05 - 24 -- 16:00:00

到目前为止,我只能按一列排序,每当我尝试使用连接或选择中的选择同时过滤2列时,我似乎无法使其正常工作。

4 个答案:

答案 0 :(得分:1)

有权访问ROW_NUMBER()的方言有最好的方法。

WITH
  sorted AS 
(
  SELECT
    yourTable.*,
    ROW_NUMBER() OVER (PARTITION BY device_id ORDER BY date_time_field DESC)  AS ordinal
  FROM
    yourTable
)
SELECT
  *
FROM
  sorted
WHERE
  ordinal = 1

其他人必须跳过更多的箍,首先找到每个设备的最新日期,然后找到重新找到相应的行。

SELECT
  yourTable.*
FROM
  yourTable
INNER JOIN
(
  SELECT
    device_id,
    MAX(date_time_field)  AS max_date_time
  FROM
    yourTable
)
  latest
    ON  latest.device_id     = yourTable.device_id
    AND latest.max_date_time = yourTable.date_time_field

答案 1 :(得分:1)

好吧,你没有标记你的DBMS,所以如果它不是MySQL,它几乎可以在任何其他DBMS上运行:

SELECT * FROM (
    SELECT t.*,
           ROW_NUMBER() OVER(PARTITION BY t.device_id ORDER BY t.date DESC, t.time DESC) as rnk
    FROM YourTable t
) s 
WHERE s.rnk = 1

答案 2 :(得分:0)

你可以这样:

select a.* from
table as a
inner join (
    select device_id, max(concat(date,time)) as mdate
    from table
    group by device_id
) as b
on (a.device_id=b.device_id and concat(a.date,a.time)=b.mdate)

但是,只有当给定设备ID的所有日期都是唯一的

时,此方法才有效

如果您在此表中有某种自动增量ID,则可以将其更改为:

select * from table
where id in (
    select max(id)
    form table
    group by device_id)

答案 3 :(得分:-2)

select * from table where deviceid in (SELECT device id ,MAX(date),max(time)
group by device id)