当前位置: 首页 > 面试题库 >

LEFT JOIN不会返回左侧表中的所有记录

归泽宇
2023-03-14
问题内容
SELECT d.mt_code,
       d.dep_name,
       d.service_name,
       COUNT(*)
FROM DepartmentService AS d
LEFT JOIN tbl_outgoing AS t ON d.mt_code = t.depCode
WHERE d.service_type = 'MT'
  AND t.smsc = "mobitelMT"
  AND t.sendDate BETWEEN '2014-07-01' AND '2014-07-02'
GROUP BY d.mt_code

DepartmentService该表包含有关提供服务的部门的详细信息。tbl_outgoing该表包含由客户完成的针对特定服务的所有交易。在该WHERE条款中,应满足两个自助餐厅service_type = 'MT' and smsc = "newMT"。我想得到一个报告,该报告显示给定期间内所有与交易有关的部门。我用过a,LEFT JOIN因为我想得到所有部门。SQL可以正常运行,并得到我想要的结果,除了,

如果在特定时期内没有针对特定服务的交易,则也将忽略该部门。我想做的是在结果集和COUNT(*)列中显示部门为0。

我怎样才能做到这一点?


问题答案:

问题可能是您正在使用where条件对联接表进行过滤,这将对联接中不匹配的部门服务进行过滤,在联接中移动过滤d,而where子句中仅保留过滤器:

SELECT d.mt_code,
   d.dep_name,
   d.service_name,
   COUNT(t.id)
FROM DepartmentService AS d
LEFT JOIN tbl_outgoing AS t 
  ON d.mt_code = t.depCode 
    AND t.smsc = "mobitelMT"
    AND t.sendDate BETWEEN '2014-07-01' AND '2014-07-02'
WHERE d.service_type = 'MT'
GROUP BY d.mt_code

为了解释为什么会发生这种情况,我将带您逐步了解查询和查询所发生的情况,作为数据集,我将使用此方法:

states
 ____ _________ 
| id | state   |
|  1 | Germany |
|  2 | Italy   |
|  3 | Sweden  |
|____|_________|

cities

 ____ ________ ___________ ____________
| id | city   | state_fk  | population |
|  1 | Berlin |        1  |         10 |
|  2 | Milan  |        2  |          5 |
|____|________|___________|____________|

首先,我将审视您的查询。

SELECT s.id, s.state, c.population, c.city
FROM states s
LEFT JOIN cities c
ON c.state_fk = s.id
WHERE c.population < 10

因此,请不要一步一步走,选择三个州,然后以城市结尾的左连接:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  1 | Germany |         10 | Berlin |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

您使用来过滤人口WHERE c.population < 10,此时您的左侧是这样的:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  2 | Italy   |          5 | Milan  |
|____|_________|____________|________|

放弃了 德国,因为柏林人口为10, 但是您也丢失了瑞典的 NULL,如果您想保留空值,则应该在查询中指定它:

WHERE (c.population < 10 OR IS NULL c.population)

哪个返回:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

现在我的查询:

SELECT s.id, s.state, c.population, c.city
FROM states s
LEFT JOIN cities c
ON c.state_fk = s.id
  AND c.population < 10

在将两者合并之前,我们过滤表城市(使用之后的AND c.population < 10条件ON),剩下的是:

 ____ ________ ___________ ____________
| id | city   | state_fk  | population |
|  2 | Milan  |        2  |          5 |
|____|________|___________|____________|

因为米兰是唯一一个人口少于10岁的城市,所以 现在 我们可以加入两个表:

 ____ _________ ____________ ________
| id | state   | population | city   |
|  1 | Germany |       NULL | NULL   |
|  2 | Italy   |          5 | Milan  |
|  3 | Sweden  |       NULL | NULL   |
|____|_________|____________|________|

你可以从左边的表停留看到的html" target="_blank">数据,因为过滤条件应用 到城市表。

结果集会根据您要实现的目标而变化,例如,如果由于柏林人口少于10个而希望过滤德国并保留瑞典,则应使用第一种方法加上IS NULL条件;如果要保留条件,则应使用第一种方法应该使用第二种方法并预先过滤左联接右侧的表。



 类似资料:
  • 问题内容: 我正在尝试使用以下查询获取每天打开的页面数。 我得到的输出是这样的: 问题是,在我的日表中,我有一列包含数字1到30来表示一个月中的天数。我进行了左外部连接,希望在天数列中显示所有天数! 但是我的查询正在这样做,为什么会这样呢? 谢谢大家的帮助。 问题答案: 解决方案是将WHERE更改为AND,以便该条件成为联接条件的一部分,而不是联接之后应用的过滤器: 现在,左表中的所有行都将出现在

  • 它还会返回这个表,遗漏一些行(我希望它给出所有流派,而不仅仅是演员在其中扮演角色的流派): 有趣的是,它为“动画”返回了“0”,但为“儿童”或“喜剧”没有行,这是我正在寻找的结果(所有流派都返回了)。我做错了什么?

  • 问题内容: 我正在尝试使用以下查询获取每天打开的页面数。 我得到的输出是这样的: 问题是,在我的日表中,我有一列包含数字1到30来代表一个月中的日子。我进行了左外部连接,希望在天数列中显示所有天数! 但是我的查询正在这样做,为什么会这样呢? 谢谢大家的帮助。 问题答案: Nanne给出的答案解释了为什么您没有得到期望的结果(您的WHERE子句删除了行),但是却没有解决方法。 解决方案是将WHERE

  • 问题内容: 我在MySQL中有以下查询: 该表有27行,但查询仅返回1行。基于 这个问题, 我认为可能是由于WHERE子句。该表具有字段id,属性,字段,值,其中是第三个表的外键(我不需要从中获取数据)。 有没有一种方法可以从第一个表中选择所有行,包括表#2中字段为23的值(如果没有字段23,则为NULL)? 问题答案: 当然。将WHERE条件移动到JOIN:

  • 问题内容: 我正在尝试读取sqlite3表中的所有记录,并通过回调返回它们。但是似乎尽管使用了序列化,但这些调用仍然是ASYNC。这是我的代码: 触发回调后,数组将打印“ []”。 我是否可以打另一个电话(而不是db.each),一次就能给我所有行。我不需要遍历这里的每一行。 如果没有,如何读取所有记录,然后才调用带有结果的回调? 问题答案: 我能够找到这个问题的答案。这是给任何正在寻找的人的:

  • 我有一个查询和一张表。查询“EmployeeTraining”包括员工姓名、参加的培训课程、参加的日期和有效期。我希望LeftJoin返回的是所有可用的培训课程,以及每个员工缺少的课程,因此在essense中,任何空值都是空的。 “应用培训”共有5项记录。一些员工只参加了4/5的课程,在“员工培训”记录中只有4项记录。left join不应该在“DateTake”和“Expiration”中使用空