MySQL:如何从一个表中选择和显示所有行,并计算另一个表中where子句的总和?

时间:2010-10-12 17:59:57

标签: sql mysql database join

我正在尝试显示一个表中的所有行,并将结果SUM / AVG放在一列中,这是where子句的结果。这可能没什么意义,所以让我解释一下。

我需要显示所有员工的报告......

SELECT Employees.Name, Employees.Extension 
FROM Employees;

--------------
| Name | Ext |
--------------
| Joe  | 123 |
| Jane | 124 |
| John | 125 |
--------------

...并加入来自PhoneCalls表的一些信息......

--------------------------------------------------------------
| PhoneCalls Table                                           |
--------------------------------------------------------------
| Ext |      StartTime      |       EndTime       | Duration |
--------------------------------------------------------------
| 123 | 2010-09-05 10:54:22 | 2010-09-05 10:58:22 |   240    |
--------------------------------------------------------------

SELECT Employees.Name, 
       Employees.Extension,
       Count(PhoneCalls.*) AS CallCount, 
       AVG(PhoneCalls.Duration) AS AverageCallTime, 
       SUM(PhoneCalls.Duration) AS TotalCallTime
FROM Employees
LEFT JOIN PhoneCalls ON Employees.Extension = PhoneCalls.Extension
GROUP BY Employees.Extension;

------------------------------------------------------------
| Name | Ext | CallCount | AverageCallTime | TotalCallTime |
------------------------------------------------------------
| Joe  | 123 |     10    |       200       |      2000     |
| Jane | 124 |     20    |       250       |      5000     |
| John | 125 |      3    |       100       |       300     |
------------------------------------------------------------

现在我想过滤掉SUM和AVG计算中包含的一些行......

WHERE PhoneCalls.StartTime BETWEEN "2010-09-12 09:30:00" AND NOW()

...理想情况下会使表看起来像这样:

------------------------------------------------------------
| Name | Ext | CallCount | AverageCallTime | TotalCallTime |
------------------------------------------------------------
| Joe  | 123 |      5    |       200       |      1000     |
| Jane | 124 |     10    |       250       |      2500     |
| John | 125 |      0    |         0       |         0     | 
------------------------------------------------------------

请注意,John没有在此日期范围内进行任何调用,因此他的总CallCount为零,但他仍然在结果列表中。我似乎无法弄清楚如何在列表中保留像John这样的记录。当我添加WHERE子句时,这些记录被过滤掉。

如何创建一个显示所有Employees的select语句,并且只显示从WHERE子句返回的值的SUM / AVG?

1 个答案:

答案 0 :(得分:7)

使用:

   SELECT e.Name, 
          e.Extension,
          Count(pc.*) AS CallCount, 
          AVG(pc.Duration) AS AverageCallTime, 
          SUM(pc.Duration) AS TotalCallTime
     FROM Employees e
LEFT JOIN PhoneCalls pc ON pc.extension = e.extension
                       AND pc.StartTime BETWEEN "2010-09-12 09:30:00" AND NOW()
 GROUP BY e.Name, e.Extension

问题是当使用OUTER JOIN时,JOIN部分中的指定条件在 JOIN发生之前应用 - 就像派生表或内联视图一样。在OUTER JOIN之后应用WHERE子句,这就是为什么当您在表上指定WHERE子句为LEFT OUTER JOIN时,您仍希望看到的行被过滤掉。