左连接不返回所有结果

Posted

技术标签:

【中文标题】左连接不返回所有结果【英文标题】:Left join not returning all results 【发布时间】:2021-03-15 19:59:58 【问题描述】:

我正在尝试连接下面的两个表,以显示事件表的所有列,以及工单表中相应记录的计数,其中事件表中的事件 ID 与事件表中的相同。

正如您在下面看到的,尚未为任何工单分配 event_id。我查询的目标是显示事件表中的所有记录以及分配给该故障单的ticket_ids 计数。我认为这会起作用,但它只返回一行:

SELECT inc.incident_id, inc.title, inc.date_opened, inc.date_closed, inc.status, inc.description, issue_type, COUNT(ticket_id) as example_count
FROM fin_incidents AS inc
LEFT OUTER JOIN fin_tickets ON inc.incident_id = fin_tickets.incident_id;

我可以使用什么查询来返回所有事件及其工单计数,即使该计数为 0?

图片:

    事件表 门票表 我的查询结果

【问题讨论】:

没有分组?您的查询无效,因此不要期望它返回正确的结果。 @philipxy,是吗?接受的答案正好相反。 @jarlh 我说看文档,接受的答案在开始时措辞不当,最后显然同意我的观点,即可以在没有分组的情况下进行聚合。整个表被视为一组,输出特殊情况是空表仍返回 1 行。这可以合理地描述为对空列集进行分组。公认的答案在其第一段中描述的是一个不同的问题。选择非聚合的非分组列有(DBMS 特定的)限制。请参阅文档。 【参考方案1】:

您的查询根本不应该工作——并且在更新版本的 mysql 中会失败。原因是它缺少GROUP BY 子句:

SELECT inc.incident_id, inc.title, inc.date_opened, 
      inc.date_closed, inc.status, inc.description, inc.issue_type,
       COUNT(t.ticket_id) as example_count
FROM fin_incidents inc LEFT OUTER JOIN
     fin_tickets t
     ON inc.incident_id = t.incident_id
GROUP BY inc.incident_id, inc.title, inc.date_opened, 
         inc.date_closed, inc.status, inc.description, inc.issue_type

您有一个没有GROUP BY 的聚合查询。这样的查询只返回一行,即使引用的表是空的。

【讨论】:

【参考方案2】:

您的代码不是有效的聚合查询。 SELECT 子句(COUNT())中有一个聚合函数,但没有 GROUP BY 子句。当在 sql 模式 ONLY_FULL_GROUP_BY 禁用的情况下执行此操作时,MySQL 会为您提供单行,其中包含与事件相关的票证总数,以及事件行中的任何值。如果启用了该 SQL 模式,则会出现编译错误。

我发现你想要的逻辑用相关子查询来表达更简单:

select i.*
    (select count(*) from fin_tickets t where t.incident_id = i.incident_id) as example_count
from fin_incidents i

此查询将利用 fin_tickets(incident_id) 上的索引 - 如果您定义了外键(您应该有),则该索引已经存在。

【讨论】:

以上是关于左连接不返回所有结果的主要内容,如果未能解决你的问题,请参考以下文章

外连接查询

MS Access:左连接不返回左表中的所有行

左连接

MariaDB - 左连接不返回所有行

左外连接和右外连接的区别

选择带有“is null”子句的查询和子选择/左连接不返回结果