外观
join 语句场景题
⭐ 题目日期:
京东 - 2024/12/26
题目描述:
T1表
Id name
1 A
2 B
3 C
T2表
name score
A 1
A 2
B 1
Select * from t1 left join t2 on t1.name = t2.name; 返回几行
Select * from t1 left join t2 on t1.name = t2.name and t2.name is not null;返回几行
Select * from t1 left join t2 on t1.name = t2.name where t2.name is not null;返回几行
📝 题解:
1. SELECT * FROM t1 LEFT JOIN t2 ON t1.name = t2.name;
- 返回行数:4 行
- 解析:
- 左连接(LEFT JOIN) 会保留左表
t1
的所有行,即使右表t2
中没有匹配的行。 - 匹配逻辑:
t1.name = A
:t2
中有两行匹配(A-1 和 A-2),生成 2 行。t1.name = B
:t2
中有一行匹配(B-1),生成 1 行。t1.name = C
:t2
中无匹配,右表字段填充NULL
,生成 1 行。
- 总行数:2 + 1 + 1 = 4 行。
- 左连接(LEFT JOIN) 会保留左表
2. SELECT * FROM t1 LEFT JOIN t2 ON t1.name = t2.name AND t2.name IS NOT NULL;
- 返回行数:4 行
- 解析:
- ON 条件 仅影响右表
t2
的匹配规则,但左表t1
的行始终保留。 - 条件逻辑:
t2.name IS NOT NULL
是冗余条件,因为t1.name
和t2.name
相等时,t2.name
必然非空(t1
的name
均为非空)。- 查询逻辑与第 1 条完全一致。
- 总行数:2(A) + 1(B) + 1(C) = 4 行。
- ON 条件 仅影响右表
3. SELECT * FROM t1 LEFT JOIN t2 ON t1.name = t2.name WHERE t2.name IS NOT NULL;
- 返回行数:3 行
- 解析:
- WHERE 条件 在连接完成后过滤结果,会剔除右表字段为
NULL
的行。 - 过滤逻辑:
t1.name = C
对应的右表字段为NULL
,被 WHERE 条件过滤。- 仅保留
t1.name = A
(2 行)和t1.name = B
(1 行)。
- 总行数:2 + 1 = 3 行。
- WHERE 条件 在连接完成后过滤结果,会剔除右表字段为
关键区别总结
查询语句 | 过滤阶段 | 逻辑差异 |
---|---|---|
LEFT JOIN ... ON t1.name = t2.name | ON 条件 | 保留所有左表行,右表无匹配则填充 NULL 。 |
LEFT JOIN ... ON t1.name = t2.name AND t2.name IS NOT NULL | ON 条件 | 右表匹配时自动满足 t2.name IS NOT NULL ,结果与第 1 条相同。 |
LEFT JOIN ... ON t1.name = t2.name WHERE t2.name IS NOT NULL | WHERE 条件 | 连接后过滤,剔除右表为 NULL 的行(如 t1.name = C 的行)。 |
图示结果
1. 第一个查询结果(4 行)
t1.id | t1.name | t2.name | t2.score |
---|---|---|---|
1 | A | A | 1 |
1 | A | A | 2 |
2 | B | B | 1 |
3 | C | NULL | NULL |
2. 第二个查询结果(4 行)
与第一个查询结果完全相同(冗余条件不影响)。
3. 第三个查询结果(3 行)
t1.id | t1.name | t2.name | t2.score |
---|---|---|---|
1 | A | A | 1 |
1 | A | A | 2 |
2 | B | B | 1 |