2012-08-23 88 views
0

我有兩個表,A和B,A包含條目列表和B爲每個條目多個狀態行(0-n,按日期分組,狀態爲0爲好,1失敗)。狀態表加入多個狀態

現在我想從A中選擇所有行,分別列出它們各自的最新狀態和日期以及最近的故障和日期(故障定義爲至少有一個條目爲1)。

我試過的東西兩個沒有加入,但我不認爲它是最佳的解決方案,也仍然有問題與確定故障的正確數量(SUM(b2.status))

SELECT a.id, b1.date, SUM(b1.status), b2.date, SUM(b2.status) FROM tablea a 
LEFT JOIN tableb b1 ON b1.aid=a.id 
LEFT JOIN tableb b2 ON b2.aid=a.id 

WHERE (b1.date=(SELECT MAX(`date`) FROM tableb WHERE aid=a.id) OR b1.date IS NULL) 
AND (b2.date=(SELECT MAX(`date`) FROM tableb WHERE aid=a.id GROUP BY `date` HAVING SUM(`status`)>0) OR b2.date IS NULL) 

GROUP BY a.id 

回答

0

哎呀,我認爲我對這一點所做的每一個假設都是錯誤的。我認爲這會給你想要的。它會給你失敗的最後日期的失敗總數。

我不知道性能如何將在一個非常大的數據庫上,但它在一個較小的工作正常。

SELECT a.id, MAX(b1.date) status_date, SUM(b1.status) latest_status, 
     b2.date latest_failure, 
     b2.total_failures 

FROM tablea a 

    LEFT JOIN tableb b1 
    ON b1.aid = a.id 
    AND b1.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id) 

    LEFT JOIN 
    (SELECT aid, date, count(*) total_failures FROM tableb WHERE status > 0 GROUP BY aid, date) b2 
    ON b2.aid = a.id 
    AND b2.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id AND status > 0) 

GROUP BY a.id; 
+0

非常感謝。這似乎是訣竅。我的第二次加入顯然不完整。 – user1616166

+0

是的,問題是,如果b1返回2行,而b2返回2行,則會得到4行,失敗次數會加倍。或者如果你有3行,它可以是三倍,等等。以上,b2只返回一行。 – Tom

0

像這樣的東西應該管用。

SELECT a.id, b1.date status_date, b1.status, b2.date latest_failure, 
     (SELECT COUNT(*) FROM tableb WHERE aid = a.id AND status > 0) total_failures 

FROM tablea a 

    LEFT JOIN tableb b1 
    ON b1.aid = a.id 
    AND b1.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id) 

    LEFT JOIN tableb b2 
    ON b2.aid = a.id 
    AND b2.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id AND status > 0) 

這是假定tableb.date字段是日期時間並且是唯一的。否則,你可能希望使用一個id字段。

+0

謝謝,既嘗試過,但不幸的是得到正確的結果。是的,日期並不是唯一的,因爲它將狀態條目分組。 – user1616166

+0

是的,如果日期不是唯一的,這是行不通的。我在想日期可能是日期時間字段。你在tableb上有獨特的ID嗎?如果是的話,最大(ID)是最新的? – Tom

+0

如果可能,我想避免引入一個id。此外,我想它只會採取最後一項,而它應該採取最後一批(按日期)。基本上,邏輯是,從A中獲取所有信息,然後加入B,並給出最新條目的日期和組合狀態以及日期和組合狀態,其中後者爲> 0(失敗)。 – user1616166

0

你也可以這樣做。不確定哪一個更有效。你可以嘗試兩種方式。

SELECT a.id, b1.date status_date, b1.status, 
     (SELECT MAX(date) FROM tableb WHERE aid = a.id AND status > 0) latest_failure, 
     (SELECT COUNT(*) FROM tableb WHERE aid = a.id AND status > 0) total_failures 

FROM tablea a 

    LEFT JOIN tableb b1 
    ON b1.aid = a.id 
    AND b1.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id) 
0

這應該有效。

SELECT a.id, MAX(b1.date) status_date, SUM(b1.status) latest_status, 
     (SELECT MAX(date) FROM tableb WHERE aid = a.id AND status > 0) latest_failure, 
     (SELECT COUNT(*) FROM tableb WHERE aid = a.id AND status > 0) total_failures 

FROM tablea a 

    LEFT JOIN tableb b1 
    ON b1.aid = a.id 
    AND b1.date = (SELECT MAX(date) FROM tableb WHERE aid = a.id) 

GROUP BY a.id; 

如果你能有一天多次失敗,並要顯示的狀態爲 「1」,則改變這種:

SUM(b1.status)latest_status

到:

MAX(b1.status)latest_status。

+0

再次感謝,但是,這仍然會計算總體失敗的總數,而不僅僅是最後一次失敗。我想我沒有解釋得很好。 A中的每個條目在B中有多個條目,這些條目是按日期分組的。每個組都是一個單獨的數據集。在這裏,我現在想要確定最近的一組總體(不管狀態)以及SUM(狀態)大於0的最新組。 – user1616166