SQL - 左连接分组

Posted

技术标签:

【中文标题】SQL - 左连接分组【英文标题】:SQL - Group By with Left Join 【发布时间】:2011-03-14 23:59:04 【问题描述】:

我有两张桌子。表 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 

【问题讨论】:

【参考方案1】:

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

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 的所有过滤器都必须在派生表中,而不是在外部 where。

【讨论】:

当您不需要通配符比较时,请小心使用 LIKE。它真的可以杀死你的查询速度。只需进行常规相等比较: WHERE call_type = 'outgoing' 进一步解释:wiki.lessthandot.com/index.php/WHERE_conditions_on_a_LEFT_JOIN 非常感谢,自从过去 4 小时以来我一直在挣扎。终于解决了。再次感谢 感谢您的回答。我在几秒钟内就得到了结果,并且很好地使用了这个示例【参考方案2】:

因为您使用的是 LEFT JOIN,所以对 LEFT JOIN 中定义的表的引用可以为空。行在那里,你只是没有看到计数值为零。这意味着您需要将此 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 标准方法。它将返回第一个非空值,但如果找不到,它将返回空值。 ISNULL 是 SQL Server 上的一个有效替代方案,但它不能移植到其他数据库,而 COALESCE 可以。这是an MSDN article comparing the two functions。

【讨论】:

不需要 COALESCE:它是 B 上的 WHERE 子句过滤器,使其成为 INNER JOIN 我试过 ISNULL 和 COALESCE,都给出了相同的结果。我可能做错了什么?我的 where 子句比我列出的要多,但它们都是确定计数所必需的。

以上是关于SQL - 左连接分组的主要内容,如果未能解决你的问题,请参考以下文章

在两个表上分组并在结果VBA ADODB SQL查询上执行左连接

MySQL更新查询与左连接和分组依据

实体框架左外连接和分组:ORA-00907:缺少右括号

将 concat 和 sum 与左连接 mysql 分组

我们如何在 MySQL 5.5 中快速进行此查询(按多列分组 + 排序,具有 2 个左连接)?

SQL中的左连接与右连接,内连接有啥区别