7.2. Table Expressions
To put this together, assume we have tables t1:
num | name -----+------ 1 | a 2 | b 3 | c
and t2:
num | value -----+------- 1 | xxx 3 | yyy 5 | zzz
then we get the following results for the various joins:
test=> create table t1 ( num int, name varchar(10)); CREATE TABLE test=> insert into t1 (num,name) values(1,'a'),(2,'b'),(3,'c'); INSERT 0 3 test=> create table t2 (num int,value varchar(10) ); CREATE TABLE test=> insert into t2 (num,value) values(1,'xxx'),(3,'yyy'),(5,'zzz'); INSERT 0 3 test=> select * from t1 cross join t2; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 1 | a | 3 | yyy 1 | a | 5 | zzz 2 | b | 1 | xxx 2 | b | 3 | yyy 2 | b | 5 | zzz 3 | c | 1 | xxx 3 | c | 3 | yyy 3 | c | 5 | zzz (9 行记录) test=> select * from t1 cross join t2 on t1.num == t2.num; 错误: 语法错误 在 "on" 或附近的 第1行select * from t1 cross join t2 on t1.num == t2.num; test=> select * from t1 inner join t2 on t1.num = t2.num; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 3 | c | 3 | yyy (2 行记录) test=> select * from t1 inner join t2 using(num); num | name | value -----+------+------- 1 | a | xxx 3 | c | yyy (2 行记录) test=> select * from t1 natural inner join t2; --num字段合并 num | name | value -----+------+------- 1 | a | xxx 3 | c | yyy (2 行记录) test=> alter table t2 rename num to num1; ALTER TABLE test=> select * from t1 natural inner join t2; --没有相同字段变为cross join num | name | num1 | value -----+------+------+------- 1 | a | 1 | xxx 1 | a | 3 | yyy 1 | a | 5 | zzz 2 | b | 1 | xxx 2 | b | 3 | yyy 2 | b | 5 | zzz 3 | c | 1 | xxx 3 | c | 3 | yyy 3 | c | 5 | zzz (9 行记录) test=> alter table t2 rename num1 to num; ALTER TABLE test=> select * from t1 left join t2 on t1.num = t2.num; --left join保证左表的行一定出现在结果集,右表没有符合条件的行用null填充 num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 2 | b | | 3 | c | 3 | yyy (3 行记录) test=> select * from t1 right join t2 on t1.num = t2.num; --right join保证右表的行一定出现在结果集,左表没有符合条件的行用null填充 num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 3 | c | 3 | yyy | | 5 | zzz (3 行记录) test=> select * from t1 full join t2 on t1.num = t2.num; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 2 | b | | 3 | c | 3 | yyy | | 5 | zzz (4 行记录) test=> insert into t1(num,name) values(3,'d'); INSERT 0 1 test=> select * from t1; num | name -----+------ 1 | a 2 | b 3 | c 3 | d (4 行记录) test=> select * from t1 left join t2 on t1.num = t2.num; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 2 | b | | 3 | c | 3 | yyy 3 | d | 3 | yyy (4 行记录)
The join condition specified with ON can also contain conditions that do not relate directly to the join. This can prove useful for some queries but needs to be thought out carefully. For example:
test=> select * from t1 left join t2 on t1.num = t2.num and t2.value = 'xxx'; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx 2 | b | | 3 | c | | 3 | d | | (4 行记录)
Notice that placing the restriction in the WHERE clause produces a different result:
test=> select * from t1 left join t2 on t1.num = t2.num where t2.value = 'xxx'; num | name | num | value -----+------+-----+------- 1 | a | 1 | xxx (1 行记录)
This is because a restriction placed in the ON clause is processed before the join, while a restriction placed in the WHERE clause is processed after the join. That does not matter with inner joins, but it matters a lot with outer joins.
出现上面不同结果的原因是因为ON的限制条件在join之前执行,为where的条件在join之后执行,但内连接不会出现这种情况,外连接会!