http://blog.csdn.net/wyzxg/article/details/7276979

三种连接的语法

为便于更多的技友快速读懂、理解,我们只讨论2张表对象进行连接操作的情况,大于2张表对象进行的连接操作原理也是一样的。

1.左连接(LEFT JOIN )

SELECT M.columnname……,N.* columnname…..

FROM left_table M LEFT JOIN right_table N ON M.columnname_join=N.columnname_join AND N.columnname=XXX

WHERE M.columnname=XXX…..

2.右连接(RIGHT JOIN)
SELECT M.columnname……,N.* columnname…..

FROM left_table M RIGHT JOIN right_table N ON M. columnname_join=N. columnname_join AND M. columnname=XXX

WHERE N.columnname=XXX…..

3.内连接

SELECT M.columnname……,N.* columnname…..

FROM left_table M [INNER] JOIN right_table N ON M. columnname_join=N. columnname_join

WHERE M.columnname=XXX….. AND N.columnname=XXX….

或者

SELECT M.columnname……,N.* columnname…..

FROM left_table M  , right_table N

WHERE M. columnname_join=N. columnname_join AND 
M.columnname=XXX….. AND N.columnname=XXX….

说明:

A.左连接(LEFT JOIN )

ON字句连接条件,用于把2表中等值的记录连接在一起,但是不影响记录集的数量。若是表left_table中的某记录,无法在表right_table找到对应的记录,则此记录依然显示在记录集钟,只是表 right_table需要在查询显示的列的值用NULL替代;

ON字句连接条件中表right_table.columnname=XXX用于控制right_table表是否有符合要求的列值还是用NULL替换的方式显示在查询列中,不影响记录集的数量;

WHERE字句控制记录是否符合查询要求,不符合则过滤掉;

简单点说,就是 “left_table.columnname_join=right_table.columnname_join”用于统计两个表的等值连接的记录集,on子句
连接条件就是限制right_table的记录集大小,where子句的条件是限制最终结果集的大小。最终结果集的大小是显示“left_table“表的所有记录,和“left_table“匹配的”right_table“的记录显示”right_table“列值,不匹配的话,显示对应的”right_table“显示为null(最终结果集的大小是left_table刨除where条件的记录数)

B.右连接(RIGHT JOIN)

ON子句连接条件,用于把2表中等值的记录连接在一起,若是表right_table中的某记录,无法在表left_table找到对应的记录,则表 left_table需要在查询显示的列的值用NULL替代;

ON子句连接条件中表left_table.columnname=XXX用于控制left_table表是否有符合要求的列值,还是用NULL替换的方式显示在查询列表中;

WHERE字句控制记录是否符合查询要求,不符合则过滤掉;

简单点说,就是 “left_table.columnname_join=right_table.columnname_join”用于统计两个表的等值连接的记录集,on子句
连接条件就是限制left_table的记录集大小,where子句的条件是限制最终结果集的大小。最终结果集的大小是显示“right_table”表的所有记录,和“right_table“匹配的”left_table“的记录显示”left_table“列值,不匹配的话,显示对应的”left_table“显示为null(最终结果集的大小是left_table刨除where条件的记录数)

C. 等值连接

ON子句连接条件,不再与左连接或右连接的功效一样,除了作为2表记录匹配的条件外,还会起到过滤记录的作用,若left_table中记录无法在right_table中找到对应的记录,则会被过滤掉;

WHERE字句,不管是涉及表left_table、表right_table上的限制条件,还是涉及2表连接的条件,都会对记录集起到过滤作用,把不符合要求的记录刷选掉;

测试数据:

创建表
mysql> CREATE TABLE left_table(ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
    -> Username VARCHAR(40) NOT NULL,
    -> Birthday DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
    -> CityID     SMALLINT NOT NULL DEFAULT 0,
    -> CreatDate  TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
    -> AlterDate  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -> PRIMARY KEY(ID),
    -> KEY idx_username(Username)
    -> )ENGINE=InnoDB CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.11 sec)

mysql> 
mysql> CREATE TABLE right_table(UID INT UNSIGNED NOT NULL ,
    -> CollectNum MEDIUMINT NOT NULL DEFAULT 0,
    -> BuyNum     MEDIUMINT NOT NULL DEFAULT 0,
    -> SearchNum  MEDIUMINT NOT NULL DEFAULT 0,
    -> CreatDate  TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
    -> AlterDate  TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    -> PRIMARY KEY(UID)
    -> )ENGINE=InnoDB CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)

插入测试数据

执行如下sql十次
 INSERT INTO left_table(Username,Birthday,CityID,CreatDate,AlterDate)
 VALUES(CONCAT(SUBSTRING(RAND(),3,8),'@qq.com'),DATE_ADD(NOW(),INTERVAL -SUBSTRING(RAND(),3,2) YEAR),SUBSTRING(RAND(),3,2),DATE_ADD(NOW(),INTERVAL -SUBSTRING(RAND(),3,3) DAY),DATE_ADD(NOW(),INTERVAL -SUBSTRING(RAND(),3,2) DAY));

执行一次如下sql
 INSERT INTO right_table
 SELECT ID,SUBSTRING(RAND(),3,4) AS CollectNum,SUBSTRING(RAND(),3,2) AS BuyNum,SUBSTRING(RAND(),3,3) AS       SearchNum,CreatDate,AlterDate FROM left_table WHERE ID%5=1;

查看基础数据:

mysql> select * from right_table;
+-----+------------+--------+-----------+---------------------+---------------------+
| UID | CollectNum | BuyNum | SearchNum | CreatDate           | AlterDate           |
+-----+------------+--------+-----------+---------------------+---------------------+
|   1 |       2545 |     78 |       171 | 2010-01-13 17:42:37 | 2011-12-16 17:42:37 |
|   6 |       4951 |     96 |       325 | 2009-11-28 17:42:55 | 2011-12-10 17:42:55 |
+-----+------------+--------+-----------+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> select * from left_table;
+----+-----------------+---------------------+--------+---------------------+---------------------+
| ID | Username        | Birthday            | CityID | CreatDate           | AlterDate           |
+----+-----------------+---------------------+--------+---------------------+---------------------+
|  1 | 27311524@qq.com | 1995-02-20 17:42:37 |      5 | 2010-01-13 17:42:37 | 2011-12-16 17:42:37 |
|  2 | 01644610@qq.com | 2004-02-20 17:42:49 |     39 | 2010-03-02 17:42:49 | 2012-01-10 17:42:49 |
|  3 | 89103050@qq.com | 1990-02-20 17:42:52 |     44 | 2010-08-28 17:42:52 | 2012-01-14 17:42:52 |
|  4 | 27363743@qq.com | 1989-02-20 17:42:53 |     32 | 2009-07-09 17:42:53 | 2011-12-03 17:42:53 |
|  5 | 09483603@qq.com | 2003-02-20 17:42:54 |     19 | 2010-03-25 17:42:54 | 2011-11-23 17:42:54 |
|  6 | 38929060@qq.com | 1987-02-20 17:42:55 |     11 | 2009-11-28 17:42:55 | 2011-12-10 17:42:55 |
|  7 | 15852433@qq.com | 1949-02-20 17:42:56 |     68 | 2010-09-17 17:42:56 | 2011-12-27 17:42:56 |
|  8 | 22581017@qq.com | 1967-02-20 17:42:57 |     59 | 2010-06-18 17:42:57 | 2012-01-24 17:42:57 |
|  9 | 54863339@qq.com | 1921-02-20 17:42:59 |     91 | 2009-11-23 17:42:59 | 2012-01-15 17:42:59 |
| 10 | 36242195@qq.com | 1940-02-20 17:43:00 |     51 | 2011-01-09 17:43:00 | 2012-01-02 17:43:00 |
+----+-----------------+---------------------+--------+---------------------+---------------------+
10 rows in set (0.00 sec)

mysql> select m.id,m.username from left_table m where m.id<=6;
+----+-----------------+
| id | username        |
+----+-----------------+
|  1 | 27311524@qq.com | 
|  2 | 01644610@qq.com | 
|  3 | 89103050@qq.com | 
|  4 | 27363743@qq.com | 
|  5 | 09483603@qq.com | 
|  6 | 38929060@qq.com | 
+----+-----------------+
6 rows in set (0.02 sec)

左连接(left join)

编号:sql_1
mysql> select m.id,m.username,n.CollectNum,n.BuyNum from left_table m left join right_table n on m.id=n.uid where m.id <=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       2545 |     78 |
|  2 | 01644610@qq.com |       NULL |   NULL |
|  3 | 89103050@qq.com |       NULL |   NULL |
|  4 | 27363743@qq.com |       NULL |   NULL |
|  5 | 09483603@qq.com |       NULL |   NULL |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
6 rows in set (0.02 sec)

编号:sql_2
mysql> select m.id,m.username,n.CollectNum,n.BuyNum from left_table m left join right_table n on m.id=n.uid and  n.SearchNum>300 where m.id <=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       NULL |   NULL |
|  2 | 01644610@qq.com |       NULL |   NULL |
|  3 | 89103050@qq.com |       NULL |   NULL |
|  4 | 27363743@qq.com |       NULL |   NULL |
|  5 | 09483603@qq.com |       NULL |   NULL |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
6 rows in set (0.00 sec)

sql_1和sql_2对比
1.两个结果集的记录数是一样的,left_table显示的列值是一样的
2.两个结果集中right_table相应列值是不一样的

为什么会不一样呢?
两个记录集的记录数是一样的,那是因为两个sql的where条件是一样,即最终的结果集的数量就会一样,right_table相应的列值不一样那是因为在on的条件中sql_2过滤掉了right_table的符合条件的记录。

右连接也就类似了,下面说下等值连接。

带join的等值连接
mysql> select m.id,m.username,n.CollectNum,n.BuyNum
    -> from left_table m inner join right_table n on m.id=n.uid
    -> where m.id<=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       2545 |     78 |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
2 rows in set (0.00 sec)

mysql> select m.id,m.username,n.CollectNum,n.BuyNum from left_table m inner join right_table n on m.id=n.uid and n.SearchNum >300 where m.id<=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
1 row in set (0.01 sec)

从上面的可以看到,这里的on有了过滤最终结果集的大小的作用了

不带join的等值连接(这种方式我用着比较舒服,因为一直用oracle的)
mysql> select m.id,m.username,n.CollectNum,n.BuyNum
    -> from left_table m,right_table n
    -> where m.id=n.uid and m.id<=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       2545 |     78 |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
2 rows in set (0.00 sec)

mysql>

常见错误用法的左连接

1.错把限制表right_table的条件,从ON子句中放到WHERE字句中,这样就会影响最终记录集大小

mysql> select m.id,m.username,n.CollectNum,n.BuyNum from left_table m left join right_table n on m.id=n.uid and  n.SearchNum>300 where m.id <=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       NULL |   NULL |
|  2 | 01644610@qq.com |       NULL |   NULL |
|  3 | 89103050@qq.com |       NULL |   NULL |
|  4 | 27363743@qq.com |       NULL |   NULL |
|  5 | 09483603@qq.com |       NULL |   NULL |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
6 rows in set (0.00 sec)

select m.id,m.username,n.CollectNum,n.BuyNum from left_table m ,right_table n where m.id=n.uid and  m.id <=6 and n.SearchNum > 300;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
1 row in set (0.00 sec)

2.错把限制表left_table或称影响最终记录集的条件,从WHERE子句中放到ON字句中,这样就相当于增大的最终结果集记录数

select m.id,m.username,n.CollectNum,n.BuyNum from left_table m ,right_table n where m.id=n.uid and  m.id <=6 and n.SearchNum > 300;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
1 row in set (0.00 sec)

mysql> select m.id,m.username,n.CollectNum,n.BuyNum from left_table m left join right_table n on m.id=n.uid and  n.SearchNum>300 where m.id <=6;
+----+-----------------+------------+--------+
| id | username        | CollectNum | BuyNum |
+----+-----------------+------------+--------+
|  1 | 27311524@qq.com |       NULL |   NULL |
|  2 | 01644610@qq.com |       NULL |   NULL |
|  3 | 89103050@qq.com |       NULL |   NULL |
|  4 | 27363743@qq.com |       NULL |   NULL |
|  5 | 09483603@qq.com |       NULL |   NULL |
|  6 | 38929060@qq.com |       4951 |     96 |
+----+-----------------+------------+--------+
6 rows in set (0.00 sec)

----------end----------

深入浅出:MySQL的左连接、右连接、内连接的更多相关文章

  1. PHP左、右、内连接

    left join   :左连接,返回左表中所有的记录以及右表中连接字段相等的记录.right join :右连接,返回右表中所有的记录以及左表中连接字段相等的记录.inner join: 内连接,又 ...

  2. SQL中的连接可以分为内连接,外连接,以及交叉连接 。

    SQL中的连接可以分为内连接,外连接,以及交叉连接 . 1. 交叉连接CROSS JOIN 如果不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积: 举例, ...

  3. mysql之索引 应用于事物 内连接、左(外)连接、右(外)连接

    什么是索引 索引就像是一本书的目录一样,能够快速找到所需要的内容 索引的作用 加快查询速率,降低IO成本加快表与表之间的连接,减少分组和排序时间 索引类型 普通索引:没有唯一性的基本索引 唯一索引:有 ...

  4. SQL Server中的连接查询【内连接,左连接,右连接,。。。】

    在查询多个表时,我们经常会用“连接查询”.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据 ...

  5. SQL 四种连接查询(内连接、左连接、右连接、全连接)

    下面列出了您可以使用的 JOIN 类型,以及它们之间的差异. (1)     JOIN: 如果表中有至少一个匹配,则返回行(inner join) (2)     LEFT JOIN: 即使右表中没有 ...

  6. 关于数据库的左,右,内,外连接,Union和Union all---------笔记

    1.左连接 select a.filed1,a.filed2,b.filed1 from a (左表) left join b(右表) on a.commonfiled = b.commonfiled ...

  7. [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Hibernate迫切左外连接和迫切内连接

    •迫切左外连接: •LEFT JOIN FETCH 关键字表示迫切左外连接检索策略. –list() 方法返回的集合中存放实体对象的引用, 每个 Department 对象关联的 Employee  ...

  9. SQL连接方式(内连接,外连接,交叉连接)

    1.内连接.左连接.右连接.全连接介绍 內连接仅选出两张表中互相匹配的记录.因此,这会导致有时我们需要的记录没有包含进来.内部连接是两个表中都必须有连接字段的对应值的记录,数据才能检索出来.   左连 ...

  10. oracle连接总结(内连接、外连接、自然连接,交叉连接,自连接)

    1.简述  1) 两个表的连接,是通过将一个表中的一列或者多列同另一个表中的列链接而建立起来的.用来连接两张表的表达式组成了连接条件.当连接成功后,第二张表中的数据就同第一张表连接起来了,并形成了复合 ...

随机推荐

  1. css经验之谈

    //清除浮动 .clear { zoom:1; }.clear:after { content:''; display:block; clear:both; }.fl { float:left; }. ...

  2. matlab中文本文件与图像转化

    一  将图片转化为txt文本文件 a=imread('picture.bmp');   //读取picture.bmp图片 b=rgb2gray(a);                 //由rgb图 ...

  3. 安装gcc

    yum -y install gcc yum -y install gcc-c++ yum install make   -- 或者 yum groupinstall "Developmen ...

  4. 从今天开始 每天记录HTML,CSS 部分的学习笔记

    从今天开始 每天记录HTML,CSS 部分的学习笔记

  5. debug fortran

    exmple: gfortran -g -fcheck=all -Wall segf.f90

  6. ESP8266 上报数据到贝壳物联

    下面贴上代码: #include <aJSON.h> #include <SPI.h> #include <Wire.h> #include <dht11.h ...

  7. Python中读取文件中的json串,并将其写入到Excel表格中

    Json:JavaScript Objective Notation,是一种轻量级的数据交换格式.Json最广泛的应用是作为AJAX中web服务器和客户端的通讯的数据格式.现在也常用语http请求中, ...

  8. python如何进行内存管理的

    python引用了一个内存池(memory pool)机制,即pymalloc机制(malloc:n,分配内存),用于管理对小块的申请和释放.

  9. 4--Selenium环境准备---chromedriver.exe 与chrome版本匹配

    0.jdk8 和eclipse 4.6 https://www.eclipse.org/downloads/packages/release/neon/3 1.selenium-server-stan ...

  10. 2017ICPC南宁赛区网络赛 Overlapping Rectangles(重叠矩阵面积和=离散化模板)

    There are nnn rectangles on the plane. The problem is to find the area of the union of these rectang ...