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

时间:2022-01-12 04:40:01

I'm trying to display all rows from one table and also SUM/AVG the results in one column, which is the result of a where clause. That probably doesn't make much sense, so let me explain.

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

I need to display a report of all employees...

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

SELECT Employees.Name, Employees.Extension 
FROM Employees;

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

...and join some information from the PhoneCalls table...

...并加入来自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     |
------------------------------------------------------------

Now I want to filter out some of the rows that are included in the SUM and AVG calculations...

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

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

...which will ideally result in a table looking something like this:

...理想情况下会导致表格看起来像这样:

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

Note that John has not made any calls in this date range, so his total CallCount is zero, but he is still in the list of results. I can't seem to figure out how to keep records like John's in the list. When I add the WHERE clause, those records are filtered out.

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

How can I create a select statement that displays all of the Employees and only SUMs/AVGs the values returned from the WHERE clause?

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

1 个解决方案

#1


7  

Use:

使用:

   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

The issue is when using an OUTER JOIN, specifying criteria in the JOIN section is applied before the JOIN takes place--like a derived table or inline view. The WHERE clause is applied after the OUTER JOIN, which is why when you specified the WHERE clause on the table being LEFT OUTER JOIN'd to that the rows you still wanted to see are being filtered out.

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

#1


7  

Use:

使用:

   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

The issue is when using an OUTER JOIN, specifying criteria in the JOIN section is applied before the JOIN takes place--like a derived table or inline view. The WHERE clause is applied after the OUTER JOIN, which is why when you specified the WHERE clause on the table being LEFT OUTER JOIN'd to that the rows you still wanted to see are being filtered out.

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