如果条件匹配,则返回2个表中的数据

时间:2014-03-04 16:08:02

标签: php mysql mysqli

我不确定该怎么做。我有网站跟踪服务器何时停机。所以我有1个表,其中包含服务器名称和ID,名为servers,另一个表中包含名为errors的错误消息。我想返回过去7天的视图日历,以显示我们的任何服务器是否发生错误。

到目前为止,我有一个查询,可以查找当天任何一台服务器的错误消息,但我不知道如何返回好的服务器并且有0个错误。

SELECT errors.error_id, servers.server_id, errors.start_time, servers.name
FROM errors
INNER JOIN servers ON errors.server_id=servers.server_id
WHERE errors.start_time BETWEEN '2014-02-25 00:00:00' AND '2014-02-25 23:59:59'

我让它循环了7天,一切正常。但我仍然坚持如何获取当天不会失效的服务器的ID和名称。我一直在考虑在查询中实现IF或CASE,但我以前从未使用它们,我不太确定它是如何工作的。

我是否需要为此运行多个查询,或者是否可以使用一个查询?

1 个答案:

答案 0 :(得分:1)

不要在日子里循环,而是一次完成所有这些。假设您每天至少有一个错误,您可以从errors表中获取此信息。否则,您可能需要一个日历表:

SELECT dates.thedate, e.error_id, s.server_id, e.start_time, s.name
FROM (select distinct date(start_time) as thedate
      from errors
      where e.start_time BETWEEN '2014-02-25 00:00:00' AND '2014-03-03 23:59:59'
     ) dates cross join
     servers s LEFT OUTER JOIN
     errors e
     ON e.server_id = s.server_id;

这将为每天每个服务器的每个错误生成一行。如果没有错误,则错误字段中每个服务器都会有一行NULL。如果你想聚合这个:

SELECT dates.thedate, s.server_id, s.name, count(*) as numErrors,
       group_concat(error_id order by e.start_time) as errorIds,
       group_concat(se.tart_time order by e.start_time) as startTimes
FROM (select distinct date(start_time) as thedate
      from errors
      where e.start_time BETWEEN '2014-02-25 00:00:00' AND '2014-03-03 23:59:59'
     ) dates cross join
     servers s LEFT OUTER JOIN
     errors e
     ON e.server_id = s.server_id and date(e.start_time) = dates.thedate
GROUP BY dates.thedate, s.server_id, s.name;

编辑:

如果没有日历表,您可以将每一天插入查询中,如下所示:

SELECT dates.thedate, s.server_id, s.name, count(*) as numErrors,
       group_concat(error_id order by e.start_time) as errorIds,
       group_concat(se.tart_time order by e.start_time) as startTimes
FROM (select date('2014-02-25') as thedate union all
      select date('2014-02-26') union all
      select date('2014-02-27') union all
      select date('2014-02-28') union all
      select date('2014-03-01') union all
      select date('2014-03-02') union all
      select date('2014-03-03') 
     ) dates cross join
     servers s LEFT OUTER JOIN
     errors e
     ON e.server_id = s.server_id and date(e.start_time) = dates.thedate
GROUP BY dates.thedate, s.server_id, s.name;