2016-05-24 111 views
2

我有一张表,用于存储设备标识,消息,日期和时间。SQL - 根据两行的最大值选择唯一记录

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

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列的筛选同时使用加入或选择内的选择,我似乎无法使其工作。

任何帮助将非常感激。先谢谢了。

+0

什么是你的RDBMS?不同的db将需要不同的解决方案 –

+0

SQL的哪个方言?将光标悬停在您的SQL标记上,您会看到有很多不同的变体... – MatBailie

+0

The one phpMyAdminUses – Razgriz

回答

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) 
+0

这两个查询都不起作用。 – sagi

+0

@sagi你能否详细说明一下? –

+0

第一个解决方案:如果在同一天有两条消息,但是时间不同,该怎么办?第二种解决方案:通过他的数据示例,没有自动增量ID。 – sagi

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 
+0

其实,据我所知,'日期'和'时间'是两个不同的列。 – sagi

+0

@sagi - 那么我有更多的问题比我想在我的答案的范围内讨论;) – MatBailie

+0

是的,只是第二个解决方案将无法工作:) – sagi

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
select * from table where deviceid in (SELECT device id ,MAX(date),max(time) 
group by device id) 
+0

这是不正确的;它会返回所有行... – jpw