分为 交叉连接,内连接和外连接
有两种,显式的和隐式的,不带on子句,返回的是两表的乘积,也叫笛卡尔积。
以下两个查询结果是相同的
-- 隐式交叉连接
select o.id, o.order_number, c.id, c.name
from orders o , customers c
-- 显式交叉连接
select o.id,o.order_number,c.id,c.name
from orders o cross join customers c
在连接条件中使用等于号(=)运算符,其查询结果中列出被连接表中的所有列,包括其中的重复列。
select * from T_student s,T_class c
where s.classId = c.classId
自然连接是一种特殊的等值连接,他要求两个关系表中进行比较的必须是相同的属性列,无须添加连接条件,并且在结果中消除重复的属性列。经MySQL验证,自然连接下不允许使用on语句
select name, course_id
from courses natural join teaches
注:
1. 连接多张表时,注意不同含义不要同名,否则会查询不到结果
-- score表存在与student表同名的sid,以及与course表同名的cid
-- course表中存在与student相同的字段name导致查询到记录为空
select * FROM score
NATURAL JOIN student
NATURAL JOIN course
-- 修改couse表name字段为cname,返回结果正常
select * FROM student s
NATURAL JOIN score sc
NATURAL JOIN course_copy cc
2. 两张表>6个字段相同时,会查询不到结果
-- student_copy表保留了6个字段
select * FROM student_copy
NATURAL JOIN student
有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行。
(所谓的链接表就是数据库在做查询形成的中间表)。
join子句中没有使用outer / inner等前缀,默认连接类型是inner join
隐式的内连接,没有inner join,一般称为等值连接,形成的中间表为两个表的笛卡尔积。
生成笛卡尔积的临时表,之后再用where后的条件进行筛选,内存占用较大
--隐式内连接,又称等值连接
select o.id,o.order_number,c.id,c.name
from customers c, orders o
where c.id=o.customer_id;
显示的内连接,一般称为内连接,有inner join,形成的中间表为两个表经过on条件过滤后的笛卡尔积
在连接其他表时,会先用on条件判断,再生成记录,查询效率优于等值连接
-- 显式内连接,简称内连接
select o.id,o.order_number,c.id,c.name
from customers c inner join orders o
on c.id=o.customer_id;
外连接分三类:左外连接(left outer join)、右外连接(right outer join)和全外连接(full outer join),
outer 关键字是省略的,通常简称为左连接(left join)、右连接(right join)和全连接(full join)
三者的共同点:
都返回符合连接条件和查询条件(即:内连接)的数据行。
不同点:
左外连接还返回左表中不符合连接条件单符合查询条件的数据行(即左表独有的数据,右表内容用null表示,只记录一条)
右外连接还返回右表中...(参照上面描述)。
全外连接还返回左表&右表中...(参照上面描述)。
左外连接(left outer join)
-- 左外连接(left outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c
on c.id=o.customer_id;
右外连接(right outer join)
-- 右外连接(right outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o right outer join customers c on c.id=o.customer_id;
全外连接(full outer join)
-- 全外连接(full outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o full outer join customers c
on c.id=o.customer_id;
注意:mysql是不支持全外的连接的(mysql中没有full outer join关键字),这里给出的写法适合oracle和db2。但是可以通过左外和右外联合查询来获取全外连接的查询结果。
-- 使用union关键字连接左外连接和右外连接
select e.empName,d.deptName
FROM t_employee e
left JOIN t_dept d
ON e.dept = d.id
UNION
select e.empName,d.deptName
FROM t_employee e
RIGHT JOIN t_dept d
ON e.dept = d.id;
补充说明:
1。on后面的条件(on条件)和where条件的区别:
on条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。
where条件:在有on条件的select语句中过滤中间表的约束条件。在没有on的单表查询中,是限制物理表或者中间查询结果返回记录的约束(此时中间表为交叉连接形成的笛卡尔积)。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。
从这里可以看出,将where条件移入on后面是不恰当的。
推荐的做法是:
on只进行连接操作,where只过滤中间表的记录,即 写连接查询的时候,on后面只跟连接条件,而对中间表限制的条件都写到where子句中。
where条件放在on后面查询的结果是不一样的。例如:
-- where条件独立书写
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c
on c.id=o.customer_id
where o.order_number<>'mike_order001';
-- 不单独使用where条件,而把条件加入on后面
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c
on c.id=o.customer_id and o.order_number<>'mike_order001';
从查询的结果来看,显然是不相同的,下面一条语句显示的结果是难以理解的。
2. 如果两张表的关联字段名相同时,可以使用USING子句,相当于where和on条件中的 "=”
-- 交叉连接,使用using
select * FROM score sc
cross JOIN course c
using(cid)
-- 使用on作为条件
select * FROM score sc
cross JOIN course c
on sc.cid=c.cid
-- 使用where条件
select * FROM score sc
cross JOIN course c
where sc.cid=c.cid
联合查询:就是把多个查询语句的查询结果结合在一起
主要语法1:... UNION ...
主要语法2:... UNION ALL ...
UNION
与 UNION ALL
的区别:联合查询支持UNION
与 UNION ALL
两种用法,其中UNION
会把多个查询语句的结果合并后去重,UNION ALL
会把所有的查询结果合并,包括重复的数据。
说明:
查询要求的列数一致(可以来自于多张表或者视图),列名可能不一致,以第一次的列名为准
推荐: 查询的每一列相对应的列类型一样
如果不同的语句中取出的行完全一致,则会合并成一行
-- 联合查询
select s1.`name` from student s1
UNION (select s2.`name` from student s2)
以上查询结果等同于单独查询一张表
以上所有内容参考以下文章整理
作者:留兰香丶
原文:https://blog.csdn.net/codejas/article/details/80227404
作者:超级阿尼玛
原文:https://blog.csdn.net/communicate_/article/details/8675759
作者:一天进步一点点lgh
原文:https://blog.csdn.net/lu0422/article/details/78892497