2009-12-10 189 views
0

我有一個看起來像一個表關係返回列第一行數據未在以下組:聚合函數由

barn 
------ 
PK barn_id 
<other columns> 

stable 
--------- 
PK stable_id 
FK barn_id 
stable_number 
stable_contents 
timestamp 

所以每當我只是把一個新行具有穩定的內容改變具有新的stable_contents和當前時間戳的相應的barn_id和stable_number。

這些表格是這樣設計的,所以我可以看看一個穩定的,看到它的整個歷史。

我想寫一個查詢,會發現我所有的馬廄的當前狀態中的所有穀倉,所以我試試這個:

SELECT barn_id, stable_number, max(timestamp), stable_contents 
FROM stable 
GROUP BY barn_id, stable_number 

在我的測試數據我有這樣的一些行穀倉1,穩定的7

1 | 7 | 2009-12-09 10:00:00 | empty 
1 | 7 | 2009-12-10 10:30:00 | show horse 

如果我運行上面的SELECT查詢,我得到了穀倉1以下返回行,穩定的7:

1 | 7 | 2009-12-10 10:30:00 | empty 

它獲得正確的最大時間戳,只是錯誤的stable_contents。

任何想法?

回答

0

它確實應該給你一個錯誤,而不是返回未定義的數據,因爲你試圖獲取不在你的GROUP BY(stable_contents)中的非聚合數據。

SELECT 
    T1.barn_id, 
    T1.stable_number, 
    T1.timestamp, 
    T1.stable_contents 
FROM 
    Stable AS T1 
LEFT OUTER JOIN Stable AS T2 ON 
    T2.barn_id = T1.barn_id AND 
    T2.stable_number = T1.stable_number AND 
    T2.timestamp > T1.timestamp 
WHERE 
    T2.barn_id IS NULL  -- The only way for this to be NULL is if no match was found 

或者:

SELECT 
    T1.barn_id, 
    T1.stable_number, 
    T1.timestamp, 
    T1.stable_contents 
FROM 
    Stable AS T1 
WHERE 
    NOT EXISTS 
    (
      SELECT 
       * 
      FROM 
       Stable AS T2 
      WHERE 
       T2.barn_id = T1.barn_id AND 
       T2.stable_number = T1.stable_number AND 
       T2.timestamp > T1.timestamp 
    ) 
+0

我選擇這一個,因爲替代形式移植到了很好的HQL。感謝所有提交。 – TheBigS 2009-12-10 18:06:54

0

您需要使用子查詢:

SELECT barn_id, stable_number, timestamp, stable_contents 
FROM stable 
WHERE (barn_id, stable_number, timestamp) IN 
(SELECT barn_id, stable_number, max(timestamp) as timestamp 
FROM stable 
GROUP BY barn_id, stable_number) 

除非你告訴它,數據庫有沒有辦法知道你想從最高時間戳行穩定的內容。你可以有幾個聚集條款max(timestamp)查詢,min(timestamp)

0
SELECT s.* 
FROM (
    SELECT barn_id, stable_number, max(timestamp) as timestamp 
    FROM stable 
    GROUP BY barn_id, stable_number) d 
INNER JOIN stable s ON s.barn_id = d.barn_id 
         AND s.stable_number = d.stable_number 
         AND s.timestamp = d.timestamp 

,它通常是一個更好的辦法有兩個表:一個包含當前狀態,另一個包含歷史數據。

0
SELECT s.* 
FROM barn b 
JOIN stable s 
ON  stable_id = 
     (
     SELECT stable_id 
     FROM stable si 
     WHERE si.barn_id = b.id 
     ORDER BY 
       barn_id DESC, timestamp DESC, stable_id DESC 
     ) 

確保你那裏沒有後一排同樣穩定,我會用下面的查詢,這對於找到一個穩定的所有行在stable (barn_id, timestamp, stable_id)上有一個複合索引,以便快速工作。

看到這篇文章在我的博客瞭解更多詳情: