2010-10-12 9 views
5

Próbuję wyświetlić wszystkie wiersze z jednej tabeli, a także SUM/AVG wyników w jednej kolumnie, która jest wynikiem klauzuli where. To prawdopodobnie nie ma większego sensu, więc pozwól mi wyjaśnić.MySQL: Jak wybrać i wyświetlić WSZYSTKIE wiersze z jednej tabeli i obliczyć sumę klauzuli where w innej tabeli?

muszę wyświetlić raport wszystkich pracowników ...

SELECT Employees.Name, Employees.Extension 
FROM Employees; 

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

... i dołączyć informacje z tabeli połączeń telefonicznych ...

-------------------------------------------------------------- 
| 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  | 
------------------------------------------------------------ 

Teraz chcę odfiltrować niektóre wiersze uwzględnione w obliczeniach SUM i AVG ...

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

... co w efekcie da zakładkę le szuka coś takiego:

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

Zauważ, że Jan nie poczyniła żadnych połączeń w tym przedziale czasowym, więc jego łączna CallCount wynosi zero, ale wciąż jest na liście wyników. Nie mogę się domyślić, jak zachować na liście takie rekordy jak John. Kiedy dodaję klauzulę WHERE, te rekordy zostaną odfiltrowane.

Jak utworzyć instrukcję select, która wyświetla wszystkich pracowników i tylko SUM/AVGs wartości zwrócone z klauzuli WHERE?

Odpowiedz

7

Zastosowanie:

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 

Problem jest, gdy za pomocą sprzężenia zewnętrznego, określając kryteria w sekcji REJESTRACJA nanosi przed JOIN odbywa się - jak pochodzącej tabeli lub widoku inline. Klauzula WHERE jest stosowana po ZŁĄCZE ZEWNĘTRZNEJ, dlatego kiedy podałeś klauzulę WHERE na tabeli LEFT OUTER DOŁĄCZYŚCIE do tego, że wiersze, które chciałeś zobaczyć, są odfiltrowywane.

+0

hmm ... to daje mi jeszcze kilka wyników, ale nie wszystkie. – Andrew

+1

Nie powinno się zapytania GROUP BY e.extension, a nie pc.extension? Jak podają, czy wszyscy pracownicy bez połączeń będą zgrupowani razem? –

+0

@djacobson: Naprawdę nie lubię polegania na [ukrytej kolumnie funkcji MySQL] (http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html) –

Powiązane problemy