2012-08-23 89 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