第四章:多表查询
4.1 笛卡儿乘积(CROSS JOIN)
1) 当多表关联查询中没有关联条件、或者关联条件是恒等的时候(如1=1),就会产出笛卡儿乘积。
2) T1有M行、T2有N行,则笛卡儿乘积返回M*N行。
4.2 连接类型
1) 如果有N个表连接,则连接条件至少应该有N-1个;如果用到复合主键进行连接,则可能需要到更多的连接条件。
2) 表的别名不能大于30个字符,如果定义了表的别名,则在select子句中,如果需要用到表名前缀,则必须要用别名,而不是用原表名。且表的别名只能用在同一层的SELECT语句中。
3) 等值连接
? 等值连接也称SIMPLE JOIN或INNER JOIN,形式是进行关联连接时用的是”=”
? 如果返回集合有重复列名,则应在重复列名前加上表名。
4) 不等连接
连接词为between...and 、”>”、“>”等。
5) 外连接
? 外连接分为左外连接、右外连接、全外连接;一个左外连接 + UNION + 右外连接等于全外连接。
? 左外连接和右外连接都可以用(+)和left(right) outer join两种方法表示,但全外连接只能用full outer join表示,而不能用两个“+”代替。
? 需要返回某表的所有记录,就把“+”写在等值关联中另一个表对应的字段上。
6) 自连接
自己与自己关联。自连接中必须要给表置别名。
7) Cross join
相当于不写where条件,得到的就是笛卡尔乘积。
8) Natural join
自然连接,不需要在where中写等值连接表达式。有几点需要注意:
? 自然连接中,连接的两个表必须有列名完全一样的列;否则返回的是笛卡尔乘积。
? 两个表有多少个相同的列名,就会进行多少个进行等值连接。
? 在SELECT子句中,如果是两个表都存在的列,则不能在这些列名前加表名前缀;否则可以加;如果需要在where子句中用两个表都存在的列作为条件,则也不能在这些列名前加上表名前缀。
如:t1和t2都有id列,以下SQL是错误的:
错误SQL:
Select t1.id from t1 natural join t2;
正确应该为:
Select id from t1 natural join t2;
错误SQL:
Select * from t1 join natural t2 where t1.id=1;
正确应该为:
Select * from t1 natural join t2 where id=1;
? 如果在select子句中用*,则返回结果相当于是对两个表的列名执行distinct后的结果。
如:
普通连接:SQL> select * from t1,t2 where t1.id=t2.id;
ID ID NAME
---------- ---------- ----------
1 1
自然连接:SQL> select * from t1 natural join t2;
ID NAME
---------- ----------
1
? 两个表的相同列对应的数据类型必须相同;或者这些列的所有数据可以隐式转换为另一个表对应的字段的数据类型。
9) JOIN...Using
? 如果两个表有多个列名相同的列,而你又不想用所有的列作关联的时候,可以用using,如:
select * from t1 join t2 using(id);
? 在SELECT子句中,如果是两个表都存在的列,则不能在这些列名前加表名前缀;否则可以加;如果需要在where子句中用两个表都存在的列作为条件,则也不能在这些列名前加上表名前缀。
? 在using中可以用一个或多个共有的列进行关联;如果是多个,则不同的列之间用“,”分隔
select * from t1 join t2 using(id,name);
10) JOIN...On
当需要用列名不相同的列进行关联时,可以用JOIN...ON:
select * from t1 join t2 on t1.id=t2.tid;
也可以用多个JOIN...ON
select * from t1 join t2 on t1.id=t2.tid join t3 on t1.name=t3.tname;