2010-04-27 88 views
2

我需要從升級請求日誌表中獲取每個設備的最新記錄。基於硬件ID和MAC地址的組合,設備是唯一的。我一直試圖用GROUP BY來做到這一點,但我不確定這是否安全,因爲它看起來可能僅僅是返回「最高記錄」(無論SQLite或MySQL認爲是什麼)。指定GROUP BY查詢的排序順序以檢索每個組的最舊或最新記錄

我希望這個「最高記錄」可以通過ORDER BY暗示,但這似乎沒有任何影響,因爲以下兩個查詢都會爲每個設備返回相同的記錄,只是順序相反:

SELECT extHwId, 
     mac, 
     created 
    FROM upgradeRequest 
GROUP BY extHwId, mac 
ORDER BY created DESC 

SELECT extHwId, 
     mac, 
     created 
    FROM upgradeRequest 
GROUP BY extHwId, mac 
ORDER BY created ASC 

是否有另一種方法可以實現這一目標?我見過幾個有點相關的帖子,都涉及到子選擇。如果可能的話,我希望在沒有子選擇的情況下做到這一點,因爲我想知道如何在沒有這個的情況下做到這一點。

+0

是三重態'extHwId,max,創建'唯一或可能有關係? – 2010-04-27 15:31:48

+0

有可能有關係。 – 2010-04-27 15:40:09

回答

2

嘗試:

SELECT extHwId, mac, MAX(created) 
FROM upgradeRequest 
GROUP BY extHwId, mac 
+0

+1由於該行中沒有其他字段被請求,所以一個簡單的group by將起作用。 – 2010-04-27 16:40:36

1

你不能 「獲得最新記錄」 使用GROUP BY。 GROUP BY將許多記錄聚合在一起,因此最終看到/提取的內容不是表中的實際記錄,而是從一個或多個表記錄構建的「虛擬」記錄。

如果您確實需要每個設備的最新記錄,則需要使用子查詢。不過,如果你只是想知道最近的戰績爲每個設備的日期,你可以通過把一個MAX聚合圍繞創建領域使用GROUP BY:

SELECT 
    extHwId, 
    mac, 
    MAX(created) 
FROM upgradeRequest 
GROUP BY extHwId, mac 
ORDER BY created ASC 
+0

正確答案,但4秒太慢。無論如何,我會給你+1,因爲你花時間給了更多的信息。 – 2010-04-27 16:42:06

0

這應該這樣做...

SELECT ur.extHwId, 
     ur.mac, 
     ur.created 
from upgradeRequest ur 
    left outer join upgradeRequest ur2 
    on ur2.extHwId = ur.extHwId 
    and ur2.mac = ur.mac 
    and ur2.Created > ur.Created -- Join with all "later" entries 
where ur2.Created is null -- Filter out all rows that have any later entries 

......但它很尷尬,可能在大型表格上表現不佳(因爲您正在閱讀和檢查幾乎每一行),並且如果有多個條目設置爲完全相同,則會產生重複最近的日期。當子查詢完成的,如下面的表格這種查詢可以更高效:

SELECT ur.extHwId, 
     ur.mac, 
     ur.created 
from upgradeRequest ur 
where not exists (select 1 
        from upgradeRequest ur2 
        where ur2.extHwId = ur.extHwId 
        and ur2.mac = ur.mac 
        and ur2.Created > ur.Created) 

這樣做的優點是數據庫引擎只發現1行中的子查詢(而不是閱讀所有行首先)過濾出一行。

+0

這兩個查詢通常都以相同的執行計劃結束(取決於基表上的唯一約束) – wqw 2010-04-27 16:12:46