SQL最强大的功能之一就是能在数据检索查询的执行中联结(join)表。联结是利用SQL的select能执行的最重要的操作,很好地理解联结及其语法是学习SQL的一个极为重要的组成部分。
① 两表关联查询
如下有两张表,用户表与角色表,用户表的外键为角色表的主键
在前面的学习中我们使用了嵌套查询,但是我们不建议使用嵌套查询,因为它效率低,推荐多表关联查询
例如,我们要查询角色为管理员的用户,并且按照user表的id排序
select user.id as user_id,username,role.name as role_name
from user,role
where role.id=user.rid and role.id=1
order by user.id;
由于没有联结条件的表关系返回的结果为笛卡尔积。检索出的行的数目将是第一个表中的行数乘第二个表中的行数。
select user.id,username,role.name as role_name
from user,role
order by username;
③内连接
查询两个表的数据
select user.id as user_id,username,role.name as role_name
from user inner join role #内连接两个表
on user.rid = role.id; #on关键字做条件
性能考虑:MySQL在运行时关联指定的每个表以处理联结,这种处理可能时非常消耗资源,因仔细考虑,不要联结不必要的表,联结的表越多,性能下降越厉害。
①使用表别名
user表与role表关联查询
select username,r.name as role_name
from user as u,role as r
where u.rid=r.id;
②自联结
select u1.id,u1.username
from user as u1,user as u2
where u1.id=u2.id and u1.id=3;
用自联结而不用子查询:自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句,虽然最终的结果一样,但有时处理联结远比处理子查询快的多。
③ 外部联结
分为左外联结和右外联结
左外联结
select user.id,username,role.name
from user left outer join role
on user.rid=role.id;
④使用带聚集函数的联结
查询管理员用户与普通用户的数量
select role.id,role.name,count(user.id) as role_num
from user inner join role
on user.rid=role.id
group by role.id;
①使用union
select id,username from user where rid=2
union #等同与条件中的or
select id,username from user where id<6;
②组合查询进行排序
select id,username from user where rid=2
union
select id,username from user where id<6
order by username;
组合不同的表,为表述比较简单,我这里使用的是相同的表,但是使用union也可以用于不同的表。
使用union,可以把多条查询的结果作为一条组合查询返回,不管它们的结果中包含还是不包含重复,使用union可极大地简化复杂的where子句,简化从多个表检索数据的工作。