mysql> desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | 0 | |
| NAME | varchar(16) | YES | | NULL | |
| AGE | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set

mysql> desc sc;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| SID | int(11) | YES | | NULL | |
| CID | int(11) | YES | MUL | NULL | |
| SCORE | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+----------------+
4 rows in set

mysql> select * from student;
+-------+----------+-----+
| ID | NAME | AGE |
+-------+----------+-----+
| 10001 | Andy | 26 |
| 10002 | Bill | 27 |
| 10003 | Caroline | 34 |
| 10004 | David | 46 |
+-------+----------+-----+
4 rows in set

mysql> select * from sc;
+----+-------+-----+-------+
| ID | SID | CID | SCORE |
+----+-------+-----+-------+
| 1 | 10001 | 101 | 78 |
| 2 | 10001 | 102 | 67 |
| 3 | 10008 | 103 | 100 |
+----+-------+-----+-------+
3 rows in set
-----------------------------------------------------------------------------------------------------------------
内连接
mysql> select student.*, sc.* from student inner join sc on student.id = sc.sid;
+-------+------+-----+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+-----+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
+-------+------+-----+----+-------+-----+-------+
2 rows in set

内连接等价于我们平时的自然连接,也就是:
mysql> select student.*, sc.* from student,sc where student.id = sc.sid;
+-------+------+-----+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+-----+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
+-------+------+-----+----+-------+-----+-------+
2 rows in set

-----------------------------------------------------------------------------------------------------------------
左连接
考虑下面的需求,我想列出所有学生对应的成绩,一个学生可能多个成绩,也可能没有成绩。有多个成绩把多个成绩列出来,没有成绩的话,成绩这些字段的值使用NULL填充。怎么解决这个问题?
使用左连接,student表 left join sc表,如下:
mysql> select student.*, sc.* from student left join sc on student.id = sc.sid;
+-------+----------+-----+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+-----+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
+-------+----------+-----+------+-------+------+-------+
5 rows in set

-----------------------------------------------------------------------------------------------------------------
右连接
考虑下面的需求,我想列出所有成绩对应的学生,一个成绩有对应的学生,也可能没有对应的学生,比如这个学生开除了。有学生就把学生列出来,没有学生的话,学生这些字段的值使用NULL填充。怎么解决这个问题?
使用右连接,student表 right join sc表,如下:
mysql> select student.*, sc.* from student right join sc on student.id = sc.sid;
+-------+------+------+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+------+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
| NULL | NULL | NULL | 3 | 10008 | 103 | 100 |
+-------+------+------+----+-------+-----+-------+
3 rows in set

根据对称性,A left join B 等价于 B right join A
-----------------------------------------------------------------------------------------------------------------
外连接
左连接也叫左外连接(同理右连接),这里的外连接也叫全外连接。
考虑下面的需求,我想列出所有学生对应的所有成绩,这里存在学生可能没有成绩,成绩也可能没有对应的学生,没有的话,也要列出来,这些字段的值使用NULL填充。
目前,mysql不支持外连接,解决办法是使用union组合查询,把左连接和右连接的结果合并。如下:
mysql> select student.*, sc.* from student left join sc on student.id = sc.sid union select student.*, sc.* from student right join sc on student.id = sc.sid;
+-------+----------+------+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+------+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
| NULL | NULL | NULL | 3 | 10008 | 103 | 100 |
+-------+----------+------+------+-------+------+-------+
6 rows in set

注意:这里的union自动去除了重复行,如果不想去除重复行,使用union all

-----------------------------------------------------------------------------------------------------------------
还有一点需要注意:就是on 之后的条件,如下:
mysql> select student.*, sc.* from student left join sc on student.id = sc.sid;
+-------+----------+-----+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+-----+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
+-------+----------+-----+------+-------+------+-------+
5 rows in set

mysql> select student.*, sc.* from student left join sc on student.id = sc.sid and sc.cid=101;
+-------+----------+-----+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+-----+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
+-------+----------+-----+------+-------+------+-------+
4 rows in set

mysql> select student.*, sc.* from student left join sc on student.id = sc.sid where sc.cid=101;
+-------+------+-----+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+-----+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
+-------+------+-----+----+-------+-----+-------+
1 row in set

这里看出第二个查询和第三个查询的区别,换一种写法就很清楚了。
mysql> select student.*, sc.* from student left join sc on (student.id = sc.sid and sc.cid=101);
+-------+----------+-----+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+-----+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
+-------+----------+-----+------+-------+------+-------+
4 rows in set

mysql> select student.*, sc.* from student left join sc on (student.id = sc.sid) where sc.cid=101;
+-------+------+-----+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+-----+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
+-------+------+-----+----+-------+-----+-------+
1 row in set

mysql> select student.*, sc.* from student left join sc on (student.id = sc.sid where sc.cid=101);
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where sc.cid=101)' at line 1

-----------------------------------------------------------------------------------------------------------------
select student.*, sc.* from student left join sc on (student.id = sc.sid and sc.cid=101); 相当于:
1、内部连接
mysql> select student.*, sc.* from student inner join sc on student.id = sc.sid;
+-------+------+-----+----+-------+-----+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+------+-----+----+-------+-----+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
+-------+------+-----+----+-------+-----+-------+
2 rows in set
2、选择出sc.cid=101,再进行左连接,没有成绩的使用NULL填充

-----------------------------------------------------------------------------------------------------------------
select student.*, sc.* from student left join sc on (student.id = sc.sid) where sc.cid=101; 相当于:
1、左连接
mysql> select student.*, sc.* from student left join sc on student.id = sc.sid;
+-------+----------+-----+------+-------+------+-------+
| ID | NAME | AGE | ID | SID | CID | SCORE |
+-------+----------+-----+------+-------+------+-------+
| 10001 | Andy | 26 | 1 | 10001 | 101 | 78 |
| 10001 | Andy | 26 | 2 | 10001 | 102 | 67 |
| 10002 | Bill | 27 | NULL | NULL | NULL | NULL |
| 10003 | Caroline | 34 | NULL | NULL | NULL | NULL |
| 10004 | David | 46 | NULL | NULL | NULL | NULL |
+-------+----------+-----+------+-------+------+-------+
5 rows in set
2、再选出 sc.cid=101

mysql 内连接 左连接 右连接 外连接的更多相关文章

  1. Python进阶----多表查询(内连,左连,右连), 子查询(in,带比较运算符)

    Python进阶----多表查询(内连,左连,右连), 子查询(in,带比较运算符) 一丶多表查询     多表连接查询的应用场景: ​         连接是关系数据库模型的主要特点,也是区别于其他 ...

  2. SQL-内连接、外连接(左、右)、交叉连接

    本文测试基于以下两个表,student(左) \ teacher(右),使用数据库MariaDB,图形化界面HeidiSQL. 连接查询的概念:根据两个表或多个表的列之间的关系,从这些表中查询数据,即 ...

  3. 在查询用户的权限的时候 使用左外连接 和 access数据库中左外连接

    一般做视图最好是做成左外连接的.而其作用尤其在我们查询用户当前的权限时尤为明显,我们将 权限表即模块表放→角色权限表→角色表→用户角色表→用户表 就这样left outer join 连接起来,这样就 ...

  4. 【MySQL作业】外连接查询——美和易思外连接查询应用习题

    点击打开所使用到的数据库>>> 1.使用左接获取所有客户的基本信息以及订购信息,要求输出客户姓名.电话.订单 ID 和下单时间. 由于需要获取所有客户的基本信息,如果采用左连接加以实 ...

  5. php操作Mysql 以及封装常用的函数 用外连接连接3个表的案例

    <?php header("content-type;text/html;charset=utf-8"); //数据库连接define('DB_HOST','localhos ...

  6. LINQ 内链接 左链接 右链接

    原文地址:http://blog.sina.com.cn/s/blog_46e9573c01014fx2.html 1.左连接: var LeftJoin = from emp in ListOfEm ...

  7. SQL 左外连接,右外连接,全连接,内连接

    原文地址  连接条件可在FROM或WHERE子句中指定,建议在FROM子句中指定连接条件.WHERE和HAVING子句也可以包含搜索条件,以进一步筛选连接条件所选的行.             连接可 ...

  8. <转>SQL 左外连接,右外连接,全连接,内连接

    本文节选自:https://www.cnblogs.com/youzhangjin/archive/2009/05/22/1486982.html       连接条件可在FROM或WHERE子句中指 ...

  9. 深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接(转)

    1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 stude ...

随机推荐

  1. python7 静态方法、类方法、属性方法 ;反射;异常处理

      #-*- coding:utf8 -*- # 静态方法@staticmethod # 静态方法(当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了.) clas ...

  2. ACM题目————网格动物

    Lattice animal is a set of connected sites on a lattice. Lattice animals on a square lattice are esp ...

  3. C# PDF添加水印

    需要iTextSharp.dll, 下载地址http://sourceforge.net/projects/itextsharp/ using System;using System.Collecti ...

  4. 第十二届浙江省大学生程序设计大赛-Demacia of the Ancients 分类: 比赛 2015-06-26 14:39 30人阅读 评论(0) 收藏

    Demacia of the Ancients Time Limit: 2 Seconds Memory Limit: 65536 KB There is a popular multiplayer ...

  5. Hangover 分类: POJ 2015-06-11 10:34 12人阅读 评论(0) 收藏

    Hangover Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 108765   Accepted: 53009 Descr ...

  6. C#中求数组的子数组之和的最大值

    <编程之美>183页,问题2.14——求子数组的字数组之和的最大值.(整数数组) 我开始以为可以从数组中随意抽调元素组成子数组,于是就有了一种想法,把最大的元素抽出来,判断是大于0还是小于 ...

  7. hbase centOS生产环境配置笔记 (1 NameNode, 1 ResourceManager, 3 DataNode)

    本次是第一次在生产环境部署HBase,本文若有配置上的不妥之处还请高手指正. hadoop版本:hadoop-2.4.1 HBase版本:hbase-0.98.6.1-hadoop2 Zookeepe ...

  8. hdu 1999 不可摸数 水题。

    不可摸数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. php修改和增加xml结点属性

    <?xml version="1.0" encoding="UTF-8" ?> <clientSet> <server url=& ...

  10. 【Thread】多线程的异常处理?

    线程中处理异常是个头疼的问题,在异步的代码中,如何将异常捕获. 捕获异常后,将异常反馈给开发者,或用户.一般来说,反馈给开发者,多数方式在是日志中打印异常日志:而反馈给用户,多数是在界面上友好提示(比 ...