笛卡尔积(交叉连接)
# 笛卡尔积的错误使用方式,缺少了多表的连接条件
SELECT A表字段,B表字段
FROM A表,B表;
# 等同于下面这种方式
SELECT A表字段,B表字段
FROM A表 CROSS JOIN B表;
# 两个表的数据都交叉匹配了一遍。
# 正确方式:需要有连接条件
SELECT A表字段,B表字段
FROM A表,B表
#两个表的连接条件
WHERE A表.xxx_id = B表.yyy_id;
等值连接 vs 非等值连接
自连接 vs 非自连接
内连接 vs 外连接
内连接:inner join / join,可以省略 inner,查询结果和交叉连接类似
外连接:outer join,outer可以省略,具体看往下看
# 7.1 等值连接 vs 非等值连接
#非等值连接的例子:
SELECT A表字段,B表字段
FROM A表,B表
#where A表.xxx between B表.xxx and B表.xxx;
WHERE A表.xxx >= B表.xxx AND A表.xxx <= B表.xxx;
#7.2 自连接 vs 非自连接
#自连接的例子:
SELECT A表字段1, A表字段2
FROM A表 m ,A表 n
WHERE m.xxx = n.xxx;
#7.3 内连接 vs 外连接
# 内连接:查询两个表匹配上的字段
SELECT A表字段,B表字段
FROM A表,B表
WHERE A表.xxx_id = B表.yyy_id;
# 外连接:左外连接、右外连接、满外连接(mysql不支持FULL OUTER JOIN)
# 左外连接(LEFT OUTER JOIN/LEFT JOIN,OUTER可以省略):左表全部数据 + 两表匹配上的数据。
# 右外连接(RIGHT OUTER JOIN/RIGHT JOIN,OUTER可以省略):右表全部数据 + 两表匹配上的数据。
以上是SQL92语法,连接条件写在where中,SQL99语法连接写在on中:
# SQL99语法的连接join...on...
SELECT A表字段,B表字段,C表字段
FROM A表 a JOIN B表 b
ON a.xxx = b.xxx
JOIN C表 c
ON b.xxx = c.xxx;
UNION 和 UNION ALL的使用
UNION:会执行去重操作
UNION ALL:不会执行去重操作
结论:如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据,则尽量使用UNION ALL语句,以提高数据查询的效率。
7种SQL JOINS的实现
左中图
#实现A - A∩B
select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
右中图
#实现B - A∩B
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
左下图
#实现查询结果是A∪B
#用左外的A,union 右外的B
select 字段列表
from A表 left join B表
on 关联条件
where 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 等其他子句;
右下图
#实现A∪B - A∩B 或 (A - A∩B) ∪ (B - A∩B)
#使用左外的 (A - A∩B) union 右外的(B - A∩B)
select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句
SQL99语法新特性(不够灵活,不推荐使用)
自然连接
SQL99 在 SQL92 的基础上提供了一些特殊语法,比如 NATURAL JOIN 用来表示自然连接。我们可以把自然连接理解为 SQL92 中的等值连接。它会帮你自动查询两张连接表中 所有相同的字段 ,然后进行 等值连接 。
在SQL92标准中:
SELECT 字段列表
FROM A表 a JOIN B表 b
ON a.key1 = b.key1
AND a.key2 = b.key2;
在 SQL99 中你可以写成:
SELECT 字段列表
FROM A表 NATURAL JOIN B表;
USING连接
当我们进行连接的时候,SQL99还支持使用 USING 指定数据表里的 同名字段 进行等值连接。但是只能配合JOIN一起使用。比如:
SELECT 字段列表
FROM A表 JOIN B表
USING (key);
你能看出与自然连接 NATURAL JOIN 不同的是,USING 指定了具体的相同的字段名称,你需要在 USING的括号 () 中填入要指定的同名字段。同时使用 JOIN...USING 可以简化 JOIN ON 的等值连接。它与下面的 SQL 查询结果是相同的:
SELECT 字段列表
FROM A表 a ,B表 b
WHERE a.key = b.key;
多表连接注意事项
我们要 控制连接表的数量 。多表连接就相当于嵌套 for 循环一样,非常消耗资源,会让 SQL 查询性能下降得很严重,因此不要连接不必要的表。在许多 DBMS 中,也都会有最大连接表的限制。
【强制】超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
说明:即使双表 join 也要注意表索引、SQL 性能。
来源:阿里巴巴《Java开发手册》