2011-06-11 97 views
0

這是我的問題的簡化版本。有兩個表有一臺機器,第二個有他們的狀態變化的信息與日期參考(不是日期,但移位索引,這就是爲什麼我必須做另一個查詢來獲取日期本身)。 我想獲得每臺機器的最後一個狀態。
我的查詢是:找到每行的最大值

SELECT * FROM machines 
LEFT JOIN (SELECT * FROM statechange, dates WHERE....ORDER BY date DESC LIMIT 0,1) AS state 
ON state.mid=machines.mid 

,但我得到只有一臺機器作爲查詢的結果。 如何在不創建視圖的情況下做到這一點?

+0

'statechange'表的主鍵是什麼? – Thomas 2011-06-11 22:18:13

+0

statechange和日期如何加入?您似乎在通過where子句使用連接,但沒有提及連接列。 – Thomas 2011-06-11 22:19:41

+0

實際上並不是日期,它是日期的索引...日期表有幾個字段包括日期,這就是狀態變化和日期如何加入。 – lvil 2011-06-11 22:27:34

回答

2
select m.*,s.`date` from machines as m 
inner join (
select mid,`date` 
from statechange 
order by `date` desc) as s 
on m.mid = s.mid 
group by m.mid 
+0

謝謝。這在我的情況下是完美的,但我怎麼能確定我得到最後的狀態?或者它是GROUP BY的一個屬性? – lvil 2011-06-11 22:21:14

+1

group by子句檢索它找到的第一條記錄。由於日期按降序排列,因此您確定會得到您想要的記錄。 – 2011-06-11 22:26:38

+0

當您不使用限制時,在派生表中是否允許使用Order By子句?這甚至意味着什麼? – Thomas 2011-06-11 22:32:38

1

假設statechange表的主鍵是你想從statechange表中返回列的東西上最大有意義(如整數)

Select ... 
From Machines As M 
    Left Join (
       Select S1.mid, Max(S1.PrimaryKeyCol) As PrimaryKeyCol 
       From statechange As S1 
        Join dates As D1 
         On D1.statechangeFK = S1.PrimaryKeyCol 
       Where D1.date = (
           Select Max(D2.date) 
           From dates As D2 
           Where D2.statechangeFK = D1.statechangeFK 
           ) 
       Group By S1.mid 
       ) As LastStateChange 
     On LastStateChange.mid = M.mid 

    Left Join statechange As S 
     On S.PrimaryKeyCol = LastStateChange.PrimaryKeyCol 

的最後一個加入的情況下。基於額外信息


修訂

Select ... 
From Machines As M 
    Left Join (
       Select S1.mid, Max(S1.PrimaryKeyCol) As PrimaryKeyCol 
       From dates As D1 
        Join statechange As S1 
         On S1.DatesForeignKeyCol = D1.PrimaryKeyCol 
       Where D1.date = (
           Select Max(D2.date) 
           From dates As D2 
            Join statechange As S2 
             On S2.DatesForeignKeyCol = D2.PrimaryKeyCol 
           Where S2.mid = S1.mid 
           ) 
       Group By S1.mid 
       ) As LastStateChange 
     On LastStateChange.mid = M.mid 

    Left Join statechange As S 
     On S.PrimaryKeyCol = LastStateChange.PrimaryKeyCol 

    Left Join dates As D 
     On D.PrimaryKeyCol = S.DatesForeignKeyCol 

一個我用上述方法的原因是考慮到場景,你可能有多個statechange行對同一middate值。上述方法將使用主鍵列作爲該場景中的決勝者。

+0

感謝您的幫助,但我已經考慮過所有可能的情況,而且我的真實查詢時間更長。 – lvil 2011-06-12 00:18:29

1

通過做這樣的事情,您可以獲得每臺機器的最新狀態信息。

SELECT mid, max(date) 
FROM statechange 
GROUP BY mid 

然後你加入,以獲得每臺機器的當前狀態。 (在列名上猜測)

SELECT m.*, sc.state, sc.date 
FROM machines m 
INNER JOIN statechange sc 
    ON (sc.mid = m.mid) 
INNER JOIN (
      SELECT mid, MAX(date) date 
      FROM statechange 
      GROUP BY mid 
      ) s 
    ON ((s.mid = sc.mid) and (s.date = sc.date)); 

雖然我認爲每個機器的當前狀態的視圖可能是非常有用的。