MySQL多表连接查询

连接(join):将一张表中的行按照某个条件(连接条件)和另一张表中的行连接起来形成一个新行的过程。

  根据连接查询返回的结果,分3类:

    内连接(inner join)

    外连接(outer join)

    交叉连接(cross join)

  根据连接条件所使用的操作符,分2类:

    相等连接(使用等号操作符)

    不等连接(不使用等号操作符)

标准的连接语法:

注意:

  在连接查询中,一个列可能出现在多张表中,为了避免引起歧义,通常在列名前面加上表名或表别名作为前缀(例:s.sid、x.sid)---使用表别名作为前缀,可以使得SQL代码较短,使用的内存更少(例:stu s,xuanke as x)。

搭建环境:模拟选课

mysql> select * from stu;
+------+--------+---------+
| sid | sname | sphonum |
+------+--------+---------+
| | 张三 | |
| | 李四 | |
| | 王五 | |
+------+--------+---------+
rows in set (0.00 sec) mysql> select * from tea;
+------+-----------+---------+
| tid | tname | tphonum |
+------+-----------+---------+
| | 相老师 | |
| | 冯老师 | |
+------+-----------+---------+
rows in set (0.00 sec) mysql> select * from course;
+------+--------+
| cid | cname |
+------+--------+
| | linux |
| | mysql |
| | hadoop |
+------+--------+
rows in set (0.00 sec) mysql> select * from xuanke;
+------+------+------+--------+
| sid | tid | cid | xuefen |
+------+------+------+--------+
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
+------+------+------+--------+
rows in set (0.00 sec)

1、内连接inner join

  只返回两张表中所有满足连接条件的行,即使用比较运算符根据每个表中共有的列的值匹配两个表中的行。(inner关键字是可省略的)

①传统的连接写法:

  在FROM子句中列出所有要连接的表的名字(进行表别名),以逗号分隔;

  连接条件写在WHERE子句中;

注意:一旦给表定义了别名,那么原始的表名就不能在出现在该语句的其它子句中

mysql> select s.sname,c.cname,t.tname,x.xuefen
-> from stu s,tea t,course c,xuanke x
-> where s.sid=x.sid and t.tid=x.tid and c.cid=x.cid;
+--------+--------+-----------+--------+
| sname | cname | tname | xuefen |
+--------+--------+-----------+--------+
| 张三 | linux | 冯老师 | |
| 李四 | linux | 冯老师 | |
| 张三 | mysql | 相老师 | |
| 李四 | mysql | 相老师 | |
| 张三 | hadoop | 相老师 | |
| 李四 | hadoop | 相老师 | |
+--------+--------+-----------+--------+
rows in set (0.08 sec)

②使用on子句(常用):笔者比较喜欢的方法,因为觉得结构清晰明了。

mysql> select s.sname,t.tname,c.cname,x.xuefen
-> from stu s
-> join xuanke x
->   on s.sid=x.sid
-> join tea t
->   on x.tid=t.tid
-> join course c
->   on c.cid=x.cid; 结果如上……

表之间的关系以JOIN指定,ON的条件与WHERE条件相同。

③使用using子句

mysql> select s.sname,t.tname,c.cname,x.xuefen
-> from stu s
-> join xuanke x
->   using(sid)
-> join tea t
->   using(tid)
-> join course c
   ->   using(cid); 结果如上……

表之间的关系以join指定,using(连接列)进行连接匹配,类似于on。(相对用的会比较少)

2、外连接outer join

  使用外连接不但返回符合连接和查询条件的数据行,还返回不符合条件的一些行。

在MySQL数据库中外连接分两类(不支持全外连接):

  左外连接、右外连接。(outer关键字可省略)。

共同点:都返回符合连接条件和查询条件(即:内连接)的数据行

不同点:

  ①左外连接还返回左表中不符合连接条件,但符合查询条件的数据行。(所谓左表,就是写在left join关键字左边的表)

  ②右外连接还返回右表中不符合连接条件,但符合查询条件的数据行。(所谓右表,就是写在right join关键字右边的表)

mysql> select s.sname,x.xuefen
-> from stu s
-> left join xuanke x
-> on s.sid=x.sid;
+--------+--------+
| sname | xuefen |
+--------+--------+
| 张三 | |
| 张三 | |
| 张三 | |
| 李四 | |
| 李四 | |
| 李四 | |
| 王五 | NULL |
+--------+--------+
rows in set (0.00 sec)

解析:stu表是左表,xuanke表是右表:left join是左连接,stu表中”王五”没有选课,在xueke表中没有数据行,不符合连接条件,返回符合查询条件的数据行,所以xuefen为null。

mysql> select s.sname,x.xuefen
-> from xuanke x
-> right join stu s
-> on x.sid=s.sid; 结果如上(用的是右连接的方式)

给连接查询附加条件:

  1、写在WHERE子句中

  2、使用AND和连接条件写在一起

!!!但是:

  对于内连接,两种写法结果相同;

  对于外连接,两种写法结果不同。

mysql> select s.sname,x.xuefen
-> from stu s
-> left join xuanke x
-> on x.sid=s.sid
->   where sname='张三';
+--------+--------+
| sname | xuefen |
+--------+--------+
| 张三 | |
| 张三 | |
| 张三 | |
+--------+--------+
rows in set (0.01 sec) mysql> select s.sname,x.xuefen
-> from (select * from stu where sname='张三') s
-> left join xuanke x
-> on x.sid=s.sid;
+--------+--------+
| sname | xuefen |
+--------+--------+
| 张三 | |
| 张三 | |
| 张三 | |
+--------+--------+
rows in set (0.00 sec)

①先连接后过滤

  select ……from ……

  left join ……

  on 连接条件

    where 过滤条件;

②先过滤后连接

  select ……from (select ……from ……where 过滤条件)

  left join ……

  on 连接条件;


3、交叉连接—笛卡尔积

  因为没有连接条件,所进行的表与表间的所有行的连接。

特点:

  ①连接查询没有写任何连接条件

  ②结果集中的总行数就是两张表中总行数的乘积(笛卡尔积)

注意:在实际中,应该要避免产生笛卡尔积的连接,特别是对于大表

mysql> select * from stu,tea,course,xuanke;
  ……
  ……
rows in set (0.00 sec)

若是想专门产生笛卡尔积,可以使用交叉连接

mysql> select *
-> from stu
-> crosss join tea;
+------+--------+---------+------+-----------+---------+
| sid | sname | sphonum | tid | tname | tphonum |
+------+--------+---------+------+-----------+---------+
| | 张三 | | | 相老师 | |
| | 张三 | | | 冯老师 | |
| | 李四 | | | 相老师 | |
| | 李四 | | | 冯老师 | |
| | 王五 | | | 相老师 | |
| | 王五 | | | 冯老师 | |
+------+--------+---------+------+-----------+---------+
rows in set (0.00 sec)

SELECT中的多表连接的更多相关文章

  1. 表连接到底咋回事,就是产生中间结果啊!用于给select/insert等操作用

    1.表连接到底咋回事,就是产生中间结果啊!用于给select/insert等操作用啊. 2.表连接产生的结果用于select/insert用 3.表连接产生的结果用于select/insert用 比如 ...

  2. 【SqlServer系列】表连接

    1   概述 1.1  已发布[SqlServer系列]文章 [SqlServer系列]MYSQL安装教程 [SqlServer系列]数据库三大范式 [SqlServer系列]表单查询 1.2  本篇 ...

  3. Hibernate中的多表查询及抓取策略

    1.Hibernate中的多表查询 1.1SQL中的多表查询 [交叉连接] select * from A,B; [内连接] 显示内连接:inner join(inner 可以省略) Select * ...

  4. SqlServer 多表连接、聚合函数、模糊查询、分组查询应用总结(回归基础)

    --exists 结合 if else 以及 where 条件来使用判断是否有数据满足条件 select * from Class where Name like '%[1-3]班' if (not ...

  5. oracle表连接——处理连接过程中另外一张表没有相关数据不显示问题

    一个数据表基本上很难满足我们的查询要求,同时,将所有的数据都保存在一个表格中显然也不是一种好的数据库设计,为了避免数据的冗余,删除.更新异常,我们通常需要建立一张外键表,通过表连接,来获取我们自己想要 ...

  6. MySQL中基本的多表连接查询教程

    一.多表连接类型1. 笛卡尔积(交叉连接) 在MySQL中可以为CROSS JOIN或者省略CROSS即JOIN,或者使用','  如: SELECT * FROM table1 CROSS JOIN ...

  7. 默认情况下,不使用of子句表示在select所有的数据表中加锁(转)

    Select …forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不 ...

  8. SQL Server中多表连接时驱动顺序对性能的影响

    本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  9. 09_MySQL DQL_SQL99标准中的多表查询(外连接)

    # 二.外连接/* 场景:查询值在1个表中出现,在另外1个表中没有出现 特点: 0.也是两张表的字段拼接,分为主表和从表 1.外连接的结果,将显示主表中的所有记录行 如果连接字段在从表中有记录,则显示 ...

随机推荐

  1. Source Map入门教程

    部署前端之前,开发者通常会对代码进行打包压缩,这样可以减少代码大小,从而有效提高访问速度.然而,压缩代码的报错信息是很难Debug的,因为它的行号和列号已经失真.这时就需要Source Map来还原真 ...

  2. Java数据结构之Set学习总结

    前言: 前面介绍了Java的数据结构List.Map,今天抽空学习总结一下另一种数据结构Set. Set介绍 Set相对于List.Map是最简单的一种集合.集合中的对象不按特定的方式排序,并且没有重 ...

  3. Permanent Generation Removal Overview(译文)

    英文原稿:http://vdisk.weibo.com/s/vxGdGZEZTEjk 中文整理稿:http://it.deepinmind.com/gc/2014/05/14/metaspace-in ...

  4. 【转】Django中的request与response对象

    关于request与response 前面几个 Sections 介绍了关于 Django 请求(Request)处理的流程分析,我们也了解到,Django 是围绕着 Request 与 Respon ...

  5. mac下安装nginx问题解决

    需要在mac上安装nginx,按照下面的博客链接一步步安装,但是碰到了些问题.下面写一下我的解决方式. (http://stevendu.iteye.com/blog/1535466) 1. 安装PC ...

  6. windows phone 8.1开发SQlite数据库操作详解

    原文出自:http://www.bcmeng.com/windows-phone-sqlite1/ 本文小梦将和大家分享WP8.1中SQlite数据库的基本操作:(最后有整个示例的源码)(希望能通过本 ...

  7. JSP配置了虚拟目录使用JavaBean报错

    今天遇到一个很棘手的问题,在jsp文件中使用useBean,网页返回码出现了500服务器内部错误,报错信息如下: The value for the useBean class attribute w ...

  8. shell学习指南-阅读笔记

    shell学习指南真不是刚开始学习shell应该看得书,虽然其中讲了简单的linux命令,shell语法等,但是每章也有些深入和生僻地方,我想如果我刚学shell看到这样的地方一定会头疼的要死.或许也 ...

  9. LVS的原理介绍

    DR模式  LVS 的VIP 和 realserver 必须在同一个网段,不然广播后所有的包都会丢掉: 提前确认LVS/硬件LB 是什么模式,是否需要在同一个网段 所有的realserver 都必须绑 ...

  10. 关于微信小程序图片失真的解决方案

    今天来说一说 关于微信小程序的图片失真问题的解决,微信小程序的image标签要设置其宽高,不然图片若宽高过大会撑开原始图片大小的区域:如下 但是宽高设置固定了会导致有些图片和规定显示图片大小的比例不一 ...