多表联合查询
多表连接查询有两种规范:
-
SQL92的规范支持如下几种多表连接查询
- 等值连接
- 非等值连接
- 外连接
- 广义笛卡儿积
-
SQL99的规范支持如下几种多表连接查询:
- 交叉连接
- 自然连接
- 使用using子句的连接
- 使用on子句的连接
- 全外连接或者左、右外连接
SQL92多表连接查询
把多个数据表都放在from之后,多个表之间以逗号隔开,连接条件放在where之后,与查询条件之间用and逻辑运算符连接;如果连接条件要求两列值相等,则称为等值连接,否则称为非等值连接,如果没有任何连接条件,则成为广义笛卡儿积
select coulumn1, coulumn2...
from table1, table2...
[where join_condition]
多表连接查询的时候可能出现两个或者多个数据列具有相同的列名,则需要在这些同名列之间使用表名前缀或者表别名前缀作为限制
select s.*, davieyang_name from davieyang_test t, davieyang_test_table tt where t.davieyang_id = tt.davieyang_id;
for t in daveiyang_test
{
for tt in davieyang_test_table
{
if(tt.davieyang_id = t.davieyuang_id)
System.out.println(tt+t)
}
}
如果是求广义笛卡儿积,则where子句后没有任何条件,结果会有n*m条记录
select s.*, davieyang_name from davieyang_test, davieyang_test_table;
select s.*, davieyang_name from davieyang_test t, davieyang_test_table tt where t.davieyang_id = tt.davieyang_id and davieyang_name is not null;
SQL92中的外连接就是在连接条件的列名后增加括号包起来的外连接符(*或+,不同的数据库有一定的区别),外连接符出现在左边时成为左外连接,出现在右边时则成为右外连接
select s.*, davieyang_name from davieyang_test t, davieyang_test_table tt where t.davieyang_id = tt.davieyang_id(*);
外连接就是在外连接符坐在的表中增加一个万能行,这行记录所有的数据都是null,而且该行可以与另一个表中所有不满足条件的记录进行匹配,通过这种方式就可以把另一个表中的所有记录选出来,不管这些记录是否满足连接条件
自连接也是一种连接用法,本质上是吧一个表当成两个表来使用,同一个表起两个别名,各数据列必须使用表别名作为前缀
create table emp_table
(
emp_id int auto_increment primary key,
emp_name varchar(255),
manager_id int,
foreign key(manager_id) references emp_table(emp_id)
);
insert into emp_table values(null, 'davieyang1', null), (null, 'davieyang2', 1), (null, 'davieyang3', 1), (null, 'davieyang4', 1),
查询数据表中所有员工名,以及每个员工对应的经理名,则必须使用自连接查询
select emp.emp_id, emp.emp_name 员工名, mgr.emp_name 经理名 from emp_table emp, emp_table mgr where emp.manager_id = mgr.emp_id;
SQL99多表连接查询
交叉连接 cross join
交叉连接的效果就是SQL92规范中的广义笛卡儿积,无须任何连接条件
select s.* , davieyang_name from davieyang_test t cross join davieyang_test_table tt;
自然连接 natural join
自然连接看起来也是无须指定连接条件的,但实际上自然连接会以两个表中的同名列作为连接条件,如果两个表中没有同名列,则自然连接与交叉连接效果完全一样
select s.*, davieyang_name from davieyang_test t natural join davieyang_test_table tt;
using子句连接
using子句可以指定一列或多列,用于显示指定两个表中的同名列作为连接条件,假如两个表中有超过一列的同名列,如果使用natural join则会把所有的同名列当成连接条件;使用using子句就可以显示的指定使用哪些同名列作为连接条件
select s.*, davieyang_name from davieyang_test t join davieyang_test_table tt using(davieyang_id);
如果使用了using子句,则必须存在对应的同名列,否则会报错
on子句连接
SQL99的连接条件都放在on子句中指定,而且每个on子句只指定一个连接条件,这意味着如果需要进行N表连接,则需要N-1个join…on对
select s.*, davieyang_name from davieyang_test t join davieyang_test_table tt on t.davieyang_id = tt.davieyang_id;
使用on子句的连接完全可以代替SQL92中的等值和非等值连接
select s.*, davieyang_name from davieyang_test t join davieyang_test_table tt on t.davieyang_id > tt.davieyang_id;
left[outer] join right[outer] join full[outer] join
这三种外连的连接条件一样通过on子句来指定,既可以是等值连接也可以是非等值连接
select s.*, davieyang_name from davieyang_test t right join davieyang_test_table tt on t.davieyang_id < tt.davieyang_id;
SQL99的外连接与SQL92外连恰好相反,SQL99左外连接将左边表中所有不满足连接条件的记录全部列出,右外连也是如此
select s.*, davieyang_name from davieyang_test t full join davieyang_test_table tt on t.davieyang_id = tt.davieyang_id;
SQL99的全外连将会把两个表中所有不满足条件的记录全部列出,但运行全连接查询会报错,因为MySQL并不支持全外连接
本文详细介绍了SQL99中多表连接的多种方式,包括交叉连接、自然连接、using子句连接、on子句连接以及各种类型的外连接(左、右、全外连接)。通过实例演示了如何处理同名列和连接条件,以及SQL99与SQL92的区别,如自然连接的隐含连接条件和全外连接的使用限制。
3350

被折叠的 条评论
为什么被折叠?



