SQL - 使用左连接分组

时间:2010-07-12 20:17:14

标签: sql sql-server tsql join

我有两张桌子。表A列出了员工姓名。表B是一个复杂的表格,其中包含员工打来的电话信息。

我的目标是创建一个包含列'name'和'callCount'的表。我的目标是通过'左连接'和'组合'来做到这一点,但我一直想念那些没有打电话的员工。我怎样才能让它保持名称并在那里放零?

也许我很亲密,有人可以指出我的拼写错误?在此先感谢您的帮助,这是SQL:

SELECT A.name, COUNT(B.call_id) AS 'outgoing call count' 
FROM EmployeeTable A 
LEFT JOIN CallTable B 
ON A.name = B.call_from_name
WHERE B.call_type LIKE 'outgoing' 
AND B.voice_mail = '0' 
...
GROUP BY A.name 

2 个答案:

答案 0 :(得分:31)

这是一个JOIN而非NULL问题:您的过滤器正在将OUTER更改为INNER JOIN。这意味着只有在CallTable(B)中有行而不是你想要的OUTER JOIN时才能获得COUNT。

SELECT A.name, COUNT(B.call_id) AS 'outgoing call count' 
FROM
   EmployeeTable A 
   LEFT JOIN
   (
   SELECT call_from_name, call_id FROM CallTable
   WHERE call_type LIKE 'outgoing' 
     AND voice_mail = '0'
     AND /* other CallTable filters */
   ) B
   ON A.name = B.call_from_name
WHERE
     /* only EmployeeTable A filters */
GROUP BY A.name 

编辑:在其他地方发表评论后,B上的所有过滤器必须位于派生表中,而不是在外部的位置。

答案 1 :(得分:2)

因为您正在使用LEFT JOIN,所以对LEFT JOIN中定义的表的引用可以为null。行就在那里,你只是没有看到计数值为零。这意味着您需要将此NULL值转换为零(在本例中):

   SELECT A.name, 
          COALESCE(COUNT(B.call_id), 0) AS 'outgoing call count' 
     FROM EmployeeTable A 
LEFT JOIN CallTable B ON B.call_from_name = A.name
                     AND B.call_type LIKE 'outgoing' 
                     AND B.voice_mail = '0' 
    WHERE ...
 GROUP BY A.name 

此示例使用COALESCE,一种处理NULL值的ANSI标准方法。它将返回第一个非null值,但如果找不到任何值,则返回null。 ISNULL是SQL Server上的有效替代方案,但在COALESCE时,它无法移植到其他数据库。这是an MSDN article comparing the two functions