SQLite多表连接时如何保留所有未匹配行?
如何在SQLite中实现多表全连接保留所有未匹配ID?
我需要对三个表进行连接操作,要确保所有表中的未匹配ID对应的行都不会被遗漏。以下是我的表结构:
Table 1
| ID | TEMP | DESC | NUMB |
|---|---|---|---|
| 32 | 89 | Y | 6 |
| 47 | NULL | Y | 5 |
| 56 | 43 | N | 4 |
| 34 | 54 | N | 3 |
| 22 | 78 | NULL | NULL |
Table 2
| ID | IND | FLAV |
|---|---|---|
| 32 | Y | G |
| 47 | N | G |
| 56 | Y | R |
| 34 | Y | B |
| 22 | Y | Y |
Table 3
| ID | COLOR | SHAPE |
|---|---|---|
| 32 | RED | SQUARE |
| 47 | BLUE | CIRCLE |
| 52 | NULL | TRI |
| 22 | ORANGE | NULL |
期望结果
我想要得到包含所有ID的结果表,包括只在单个表中存在的ID(比如ID 52):
| ID | TEMP | DESC | NUMB | IND | FLAV | COLOR | SHAPE |
|---|---|---|---|---|---|---|---|
| 32 | 89 | Y | 6 | Y | G | RED | SQUARE |
| 47 | NULL | Y | 5 | N | G | BLUE | CIRCLE |
| 56 | 43 | N | 4 | Y | R | NULL | NULL |
| 34 | 54 | N | 3 | Y | B | NULL | NULL |
| 22 | 78 | NULL | NULL | Y | Y | ORANGE | NULL |
| 52 | NULL | NULL | NULL | NULL | NULL | NULL | TRI |
我尝试过的SQL
SELECT * FROM Table1 INNER JOIN Table2 USING(ID) LEFT JOIN Table3 USING(ID)
但这条语句会遗漏ID为52的行,因为它只存在于Table3中,而INNER JOIN只保留了Table1和Table2都有的ID。请问在SQLite中是否可以实现保留所有未匹配ID的连接?
当然可以实现!问题出在你最初的查询用了INNER JOIN,它只保留同时存在于Table1和Table2的ID,所以Table3里独有的ID 52直接被排除了。而SQLite本身不支持FULL OUTER JOIN(这是很多数据库用来保留所有表记录的语法),不过我们可以用下面的方法模拟全连接效果:
解决方案步骤:
- 先收集三个表中所有不重复的ID,用
UNION来自动去重得到唯一ID集合; - 以这个ID集合为基础,分别对三个表做
LEFT JOIN,这样所有ID都会被保留,对应表中没有该ID的字段会自动填充为NULL。
最终SQL语句:
WITH AllIDs AS ( SELECT ID FROM Table1 UNION SELECT ID FROM Table2 UNION SELECT ID FROM Table3 ) SELECT a.ID, t1.TEMP, t1.DESC, t1.NUMB, t2.IND, t2.FLAV, t3.COLOR, t3.SHAPE FROM AllIDs a LEFT JOIN Table1 t1 USING(ID) LEFT JOIN Table2 t2 USING(ID) LEFT JOIN Table3 t3 USING(ID);
简单解释:
WITH AllIDs AS (...)是一个公共表表达式(CTE),用来一次性获取三个表的所有唯一ID,UNION会自动帮我们去掉重复的ID;- 从这个全量ID集合出发左连接三个表,就能保证每个ID都出现在结果里,没有匹配到的字段自然显示为
NULL,完全符合你想要的结果。
运行这条语句就能得到包含所有ID的目标表啦!
内容的提问来源于stack exchange,提问作者anni
相关产品推荐
相关产品推荐

