连表查询;
内连接:只显示匹配的数据
交叉连接 : cross
优点:简单
两个表的数据条数相乘就是笛卡尔积: 笛卡尔积没有实际意义,有理论意义,让我们明白连接查询底层的原理
menu表 与 role表 查询两个表的全部字段 * cross可以省略不写
select * from menu cross join role
自然连接 natural
会自动匹配所有的同名列(并且同名列只保留一列)
select rid ,username,fid ,id,url,fid from role natural join menu
缺点:没有指明各列属于那个表,效率低下
解决:指定表明
select role.rid ,role.username,role.fid ,menu.id,menu.url,menu.fid from role natural join menu
上面的表明有时可能会比较长,所以把表指定别名
select r.rid ,r.username,r.fid ,m.id,m.url,m.fid from role r natural join menu m
using子句:
nutural自然连接的缺点:会自动的按照(所有的)同名列进行匹配,如果希望只按照某个同名列匹配怎么解决,使用using子句
select r.rid ,r.username,r.fid ,m.id,m.url,m.fid from role r join menu m using(fid) --r.fid = d.fid 只列举出来满足条件的
using,nutural的缺点:必须有同名列,主键外键不同明名的情况下要用on子句
on子句
select r.rid ,r.username,r.fid ,m.id,m.url,m.fid from role r join menu m on(r.fid = m.id) --括号中指明给 role表的fid等于menu表的id
总结:到底什么时候用哪种连接(join)查询
cross 不用 当你不知道怎么写查询语句的时候使用交叉查询分析一下,再根据需要选择用那个
natural,using : 必须有同名列
on 不管是否有同名列,均可使用,可读性强
建议使用on
select r.rid ,r.username,r.fid ,m.id,m.url,m.fid from role r join menu m on(r.fid = m.id) where rid >1
语句后都可以追加where条件进行查询
外连接:还可以显示全部或者部分不匹配的数据
左外连接 left outer join outer可以省略不写 :除了显示匹配数据,还可以显示左表不匹配的数据
select * from role r LEFT JOIN menu m on (r.rid = m.fid)
右外连接 right outer join :除了显示匹配数据,还可以显示右表不匹配的数据
select * from role r RIGHT JOIN menu m on (r.rid = m.fid)
全外连接 full outer join:除了显示匹配数据,还可以显示左表右表不匹配的数据
需要注意的是:MySQL到现在位置还不支持全外连接 Oracle支持
select * from role r full JOIN menu m on (r.rid = m.fid)
MySQL实现全外连接可以使用 union 把左外连接右外连接链接起来查询就可以实现全外连接
select * from role r RIGHT JOIN menu m on (r.rid = m.fid) UNION select * from role r left JOIN menu m on (r.rid = m.fid)
但是union 查询出来的数据有一个缺点 会去重、
使用union all 则不会去重
select * from role r RIGHT JOIN menu m on (r.rid = m.fid) UNION select * from role r left JOIN menu m on (r.rid = m.fid)
使用union 去重固然好 但是查询效率低 union all 查询效率高