mySQL复杂的多表查询

时间:2013-07-09 16:10:00

标签: mysql multi-table

我的问题是我甚至不知道这种查询是否可行。我会试着解释一下:

我有两个关于电话呼叫的表,“呼叫”和“Failed_Calls”。

两个表中的重要列都是“Destination”和“Route”,但还有更多像Id_call和start_date以及called_number等等。我将省略关于时间段的过滤器以简化。 “Failed_Calls”中不存在“Calls”中的目的地,反之亦然。

我想得到,为每个可能的目的地和路线对,呼叫计数和失败的呼叫计数,如下面的代码:

select c.Destination, c.Route, count(c.id_call) as Correct, null as Failed 
from Calls c
where c.Destination like ('Algeria%')
group by c.Destination, c.Route
union all
select f.Destination, f.Route, null, count(f.id_failed_call) as Failed
from Failed_Calls f
where f.Destination like ('Algeria%')
group by f.Destination, f.Route

它显示:

Destination    Route   Correct   Failed
Algeria        9       1         NULL
Algeria Mobile 9       4         NULL
Algeria Mobile 9       NULL      2

...这是正确的,但我需要在一行上显示最后两行的数据,即该目的地和路由的正确和失败呼叫的计数。

我尝试过加入,离开加入但没有加入,但我总是得到一个糟糕的计数,类似于每对夫妇的通话和失败通话的产品。我迄今为止最好的射门是:

select c.Destination, c.Route, count(distinct(c.id_call)) as Correct,
 count(distinct(f.id_failed_call)) as Failed
from Calls c, Failed_Calls f
where c.Destination like 'Algeria%'
 and f.Destination like 'Algeria%'
group by c.Destination, c.Route

...返回以下内容:

Destination     Route     Correct    Failed
Algeria         9         1          2
Algeria Mobile  9         4          2

“正确”列是正常的,但“失败”列显示所有返回目的地的失败呼叫总和,每行 (我已在查询中检查了更多目的地)。

如果可以进行此类查询,我希望有人可以帮助我。

4 个答案:

答案 0 :(得分:0)

在这种情况下我没有尝试过,但我之前使用过这样的查询来总结来自UNIONs的数据。

select Destination, route, sum(Correct), sum(Failed ) from (
    select c.Destination, c.Route, count(c.id_call) as Correct, 0 as Failed 
    from Calls c
    where c.Destination like ('Algeria%')
    group by c.Destination, c.Route
    union all
    select f.Destination, f.Route, 0 as Correct, count(f.id_failed_call) as Failed
    from Failed_Calls f
    where f.Destination like ('Algeria%')
    group by f.Destination, f.Route) as temp_table
group by Destination, route;

答案 1 :(得分:0)

尝试类似的东西:

select c.Destination, c.Route, SUM(c.id_call) as Correct,
SUM(case when f.id_failed_call is NULL then 0 else 1 end)) as Failed
from Calls c, Failed_Calls f
where c.Destination like 'Algeria%'
and f.Destination like 'Algeria%'
group by c.Destination, c.Route

答案 2 :(得分:0)

您应该能够将您的工作查询基本打包到外部选择中,并将行分组到那里;

SELECT Destination, Route,
       COALESCE(SUM(Correct), 0) Correct, COALESCE(SUM(Failed), 0) Failed
FROM (
  SELECT c.Destination, c.Route, COUNT(c.id_call) as Correct, NULL AS Failed 
  FROM Calls c
  WHERE c.Destination like ('Algeria%')
  GROUP BY c.Destination, c.Route
  UNION ALL
  SELECT f.Destination, f.Route, NULL, COUNT(f.id_failed_call) AS Failed
  FROM Failed_Calls f
  WHERE f.Destination LIKE ('Algeria%')
  GROUP BY f.Destination, f.Route
)
GROUP BY Destination, Route;

答案 3 :(得分:0)

尝试

SELECT dr.DESTINATION,
       dr.ROUTE,
       IFNULL(c.CORRECT_COUNT, 0) AS CORRECT_COUNT,
       IFNULL(f.FAILED_COUNT, 0) AS FAILED_COUNT
  FROM (SELECT DISTINCT DESTINATION, ROUTE
          FROM CALLS
        UNION DISTINCT
        SELECT DISTINCT DESTINATION, ROUTE
          FROM FAILED_CALLS) dr
  LEFT OUTER JOIN (SELECT DESTINATION,
                          ROUTE,
                          COUNT(DISTINCT ID_CALL) AS CORRECT_COUNT
                     FROM CALLS
                     GROUP BY DESTINATION, ROUTE) c
    ON (c.DESTINATION = dr.DESTINATION AND
        c.ROUTE = dr.ROUTE)
  LEFT OUTER JOIN (SELECT DESTINATION,
                          ROUTE,
                          COUNT(DISTINCT ID_CALL) AS FAILED_COUNT
                     FROM FAILED_CALLS
                     GROUP BY DESTINATION, ROUTE) f
    ON (f.DESTINATION = dr.DESTINATION AND
        f.ROUTE = dr.ROUTE)

dr子查询获得DESTINATION和ROUTE的所有可能组合 - 使用UNION DISTINCT表示应删除重复项。

c子查询然后加入每个目的地和路线的“正确”计数,如果存在这样的计数。

f子查询然后加入每个目标和路由的“失败”计数,如果存在这样的计数。

Sqlfiddle here

分享并享受。