我正在尝试显示一个表中的所有行,并将结果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?
答案 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时,您仍希望看到的行被过滤掉。