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. 3301: [USACO2011 Feb] Cow Line

    3301: [USACO2011 Feb] Cow Line Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 82  Solved: 49[Submit ...

  2. Java设计模式之职责型模式总结

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6548127.html 所谓职责型模式,就是采用各种模式来分配各个类的职责. 职责型模式包括 ...

  3. 【转】Django HTTP请求的处理流程

    Django 和其他 Web 框架的 HTTP 处理的流程大致相同,Django 处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的.我们可以在 Middlewar ...

  4. HTML——超文本标记语言(表单及12个表单元素)

    表单 格式: <form action=" " method="get/post"  placehoder=" "></f ...

  5. 极客君教你破解隔壁妹子的wifi密码,成功率高达90%

    首先,给大家推荐一个我自己维护的网站: 开发者网址导航:http://www.dev666.com/ 破解wifi密码听起来很复杂,实际上也不是非常的复杂,极客君(微信公众帐号:极客峰)今天教大家如何 ...

  6. iOS开发之NSObject的多线程

    1.NSObject的多线程方法(用的时候要用@autoreleasepool{}包起来) 开启后台执行任务的方法: - (void)performSelectorInBackground:(SEL) ...

  7. letter-spacing+first-letter实现按钮文字隐藏

    本文地址:http://www.zhangxinxu.com/wordpress/?p=3557 一.文不在长,有货则灵 图片式按钮的文字隐藏看来是大家都比较关注的一个问题(分享讨论.微博转发等可见一 ...

  8. while循环学习之统计流量

    /application/apache/logs/bbs-access_log日志文件中任意一行的格式如下,以空格为间隔第十列(2632)为此次请求内容的字节数大小 192.168.220.1 - - ...

  9. React虚拟DOM具体实现——利用节点json描述还原dom结构

    前两天,帮朋友解决一个问题: ajax请求得到的数据,是一个对象数组,每个对象中,具有三个属性,parentId,id,name,然后根据这个数据生成对应的结构. 刚好最近在看React,并且了解到其 ...

  10. 【一通百通】c/php的printf用法

    1.先说说PHP printf()函数: printf()函数的调用格式为: printf("<格式化字符串>", <参量表>); %d 十进制有符号整数  ...