小编典典

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

sql

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,LEFTJOIN因为我想得到所有部门。SQL可以正常运行,并得到我想要的结果,除了,

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

我怎样才能做到这一点?


阅读 724

收藏
2021-03-23

共1个答案

小编典典

问题可能是您正在使用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   |
|____|_________|____________|________|

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


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

2021-03-23