2016-05-24 119 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