使用 WHERE 子句加入多个表,包括没有公共 ID 的行
Posted
技术标签:
【中文标题】使用 WHERE 子句加入多个表,包括没有公共 ID 的行【英文标题】:Multiple tables JOIN with WHERE clause including rows that haven't common id 【发布时间】:2020-11-15 12:39:06 【问题描述】:我想这个话题已经在这里讨论过了。但是我找不到对我的问题有用的东西,因此欢迎提供链接。
一共有三张桌子。表test2
有两个表test1
和test3
的外键。
test1 test2 test3
+----+------+ +----+-------+-------+----+ +----+------------+
| id | name | | id | t1_id | t3_id | v2 | | id | co_date |
+----+------+ +----+-------+-------+----+ +----+------------+
| 1 | A | | 1 | 3 | 1 | 15 | | 1 | 2018-12-02 |
| 2 | B | | 2 | 4 | 1 | 20 | | 2 | 2019-02-03 |
| 3 | C | | 3 | 9 | 2 | 35 | | 3 | 2019-03-04 |
| 4 | D | | 4 | 5 | 3 | 12 | | 4 | 2019-04-05 |
| 5 | E | | 5 | 6 | 3 | 12 | | 5 | 2019-09-01 |
| 6 | F | | 6 | 9 | 4 | 20 | | 6 | 2019-10-02 |
| 7 | G | | 7 | 6 | 5 | 10 | | 7 | 2019-11-03 |
| 8 | H | | 8 | 7 | 5 | 10 | | 8 | 2019-12-04 |
| 9 | I | | ....................... | | 9 | 2020-02-05 |
| 10 | J | | 20 | 4 | 10 | 30 | | 10 | 2020-03-06 |
+----+------+ +----+-------+-------+----+ +----+------------+
我想在特定时期内按名称对test2
中的所有 v2 值求和。问题是在那个时期没有出现一些名字。并且它们被排除在查询结果之外。
我尝试使用左手连接,但它不起作用。
SELECT t1.name, SUM(v2) FROM test1 as t1
LEFT OUTER JOIN test2 as t2
ON t1.id = t2.t1_id
LEFT OUTER JOIN test3 as t3
ON t2.t3_id = t3.id
WHERE co_date BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY name
ORDER BY name
以下结果不包括 'A'
到 'D'
的名称。
+------+---------+
| name | SUM(v2) |
+------+---------+
| E | 26 |
| F | 37 |
| G | 35 |
| H | 10 |
| I | 90 |
| J | 20 |
+------+---------+
但我希望他们应该与NULL
在其他领域。 LEFT JOIN
的工作方式不就是这样:左表中的所有行以及与其他表的交集吗?
另外,我尝试过笛卡尔积,但我不知道如何正确分组。
Here's the demo。 对于我应该如何思考的任何建议,我将不胜感激。
【问题讨论】:
【参考方案1】:您需要在ON
子句中包含日期过滤器:
SELECT t1.name, SUM(v2)
FROM test1 t1 LEFT JOIN
test2 t2
ON t1.id = t2.t1_id LEFT JOIN
test3 t3
ON t2.t3_id = t3.id AND
t3.co_date BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY t1.name
ORDER BY name;
WHERE
子句将外连接变为内连接——这就是丢失行的原因。这样做是因为 NULL
未能在 WHERE
子句中过滤“外部连接”结果的比较。
【讨论】:
为什么没有在各种 JOIN 类型描述中说明它?.. 谢谢你,Gordon。 @Gennadiy:他们没有明确这样做,但他们提到外部连接的列是空的,所以WHERE t3.co_date BETWEEN DATE '2019-01-01' AND DATE '2019-12-31'
必须忽略这些行。以上是关于使用 WHERE 子句加入多个表,包括没有公共 ID 的行的主要内容,如果未能解决你的问题,请参考以下文章