• 1
  • 2
  • 3
  • 4
  • 5
mysql数据库问题 首 页  »  帮助中心  »  数据库  »  mysql数据库问题
MySQL:join语句类型
发布日期:2016-4-16 22:4:47

  MySQL:join语句类型

  join从句的类型有以下几种:

  内链接(inner)

  右外连接(right outer)

  左外连接(left outer)

  全外连接(full outer)

  交叉链接(cross)

  连接条件:使用ON设定连接条件,也可以用WHERE代替

  · ON:设定连接条件

  · WHERE:进行结果集记录的过滤

  一,内连接inner join:

  内连接是返回左表及右表符合连接条件的记录,在MySQL中JOIN与INNER JOIN是等价的

  语法为:select a.user_name,a.over,b.over from user1 as a join user2 as b on a.user_name=b.user_name;

  ( 选择表中字段 ) (a为user1别名) ( 公共部分 )

  例如:SELECT * FROM tabA JOIN tabB ON tabA.name = tabB.name;表示返回都含有的name值对应的字段

  其连接关系如下图所示:

  

  二,右外连接:left outer join

  显示右表中的全部记录和左表中符合连接条件的记录

  如果某字段只存在某一表,那么另一表的里字段返回 NULL

  以下语句查询出A表中的key和B表中的key相等的部分 ,而结果查询出了B表中所有的数据和B表和A表相同的部分

  select from tableA A right join TableB B on A.key=B.key

  以下语句查询出A表中的key和B表中的key相等的部分,而结果查询出了B表中有的,而A表中没有的数据,效果类似于inner join

  select from tableA A right join TableB B on A.key=B.key where B.key IS NULL

  它的连接关系图如下所示:

  

  三,左外连接:left outer join

  显示左表中的全部记录和右表中符合连接条件的记录

  若某字段只存在某一表,则另一表的里字段返回 NULL

  以下语句查询出A表中的key和B表中的key相等的部分 ,而结果查询出了A表中所有的数据和B表和A表相同的部分

  select from tableA A left join TableB B on A.key=B.key

  以下语句查询出A表中的key和B表中的key相等的部分,而结果查询出了A表中有的,而B表中没有的数据,效果类似于inner join

  select from tableA A left join TableB B on A.key=B.key where B.key IS NULL

  它的连接关系图如下所示:

  

  四,交叉连接

  (笛卡尔积连接):A*B,其实就是将两个表进行相乘,一般项目中很少用到笛卡尔积连接

  select * from user1 a cross join user2 b;

  如上语句:如果user1表中有3条记录,user2中有4条记录,则结果就有12条记录

  五,MySQL 中 不会支持 full join

  解决方法:采用左连接和右连接结合+ union all 方法来取得两表的合集

  select a.user_name , a.over , b.over <-这里是指所选择显示的项

  from user1 a

  left join user2 b on a.user_name = b.user_name <-这里是指筛选条件

  union all <-连接反向查询语句

  select b.user_name , b.over, a.over <-这里是指所选择显示的项

  from user1 a

  right join user2 b on a.user_name = b.user_name <-这里是指筛选条件

  六,MySQL 联合更新技巧:

  题目:将user1表中user_name与user2表中user_name相同的user1表的over替换成user2表中的over值?

  一般的正常思路:

  update user1

  set over='齐天大圣'

  where user1.user_name in(

  select b.user_name from user1 a left join user2 b on a.user_name = b.user_name);

  这样去执行思路上是对的,但是MySQL不支持这种机制

  解决方法:

  update user1 a

  join (

  select b.user_name from user1 a join user2 b on a.user_name = b.user_name

  ) b on a.user_name = b.user_name set a.over='齐天大圣'

  七,join优化子查询技巧:

  一般子查询写法:(数据小时,没有多大影响,如果数据量大时,则要消耗大量的查询)

  select a.user_name , a.voer , (select over from user2 where a.user_name = b,user_name) as over2

  from user1 a;

  join优化后的写法如下所示:

  select a.user_name , a.over , b.over from user1 a

  left join user2 b on a.user_name = b.user_name

  八,MySQL 使用join优化聚合子查询:

  

  问题:如何查询出四人组中打怪最多的日期?

  一般思路:聚合子查询

  select a.user_name , b.timestr , b.kills

  from user1 a join user_kills b on a.id = b.user_id

  where b.kills = (select MAX(c.kills) from user_kills c where c.user_id = b.user_id)

  优化后的方法:

  select a.user_name , b.timestr , b.kills

  from user1 a

  join user_kills b on a.id = b.user_id

  join user_kills c on c.user_id = b.user_id

  group by a.user_name , b.timestr , b.kills

  having b.kills = MAX(c.kills)

  九,分类聚合方式查询每一个用户某一个字段数据最大的两条数据:

  select d.user_name ,c.ctimestr,kills from

  (select user_id ,timestr ,kills ,(

  select count(*) from user_kills b where b.user_id = a.user_id and a.kills <= b.kills) as cnt

  from user_kills a group by user_id,timestr,kills) c

  join user1 d on c.user_id = d.id where cnt <= 2