精华内容
下载资源
问答
  • 左链接
    万次阅读
    2020-01-12 21:55:30

    /*
    左连接:
    第一种结果:A
    select 字段列表
    from A表 left join B表
    on 关联条件

    第二种结果:A - A∩B
    select 字段列表
    from A表 left join B表
    on 关联条件
    where 从表的关联字段 is null

    左连接和右连接的区别:
    (1)left换成right
    (2)以左边的表为主还是以右边的表为主
    右连接
    第一种结果:B
    select 字段列表
    from A表 right join B表
    on 关联条件

    第二种结果:B - A∩B
    select 字段列表
    from A表 right join B表
    on 关联条件
    where 从表的关联字段 is null
    */

    #查询所有员工和他的部门编号,部门名称,包括那些没有部门的员工
    SELECT *
    FROM t_employee LEFT JOIN t_department
    ON t_employee.did = t_department.did

    #查询所有没有部门的员工
    #不用关联查询也可以实现
    SELECT * FROM t_employee WHERE did IS NULL

    #用关联查询
    SELECT *
    FROM t_employee LEFT JOIN t_department
    ON t_employee.did = t_department.did
    WHERE t_employee.did IS NULL

    更多相关内容
  • Oracle 左连接、右连接、全外连接、(+)号详解 1、左外连接(LEFT OUTER JOIN/ LEFT JOIN) 2、右外连接(RIGHT OUTER JOIN/RIGHT JOIN) 3、全外连接(FULL OUTER JOIN/FULL JOIN) 4、补充 5、Oracle中 (+)...

    目录

    Oracle 左连接、右连接、全外连接、(+)号详解

    1、左外连接(LEFT OUTER JOIN/ LEFT JOIN)

    2、右外连接(RIGHT OUTER JOIN/RIGHT JOIN)

    3、全外连接(FULL OUTER JOIN/FULL JOIN)

    4、补充

    5、Oracle中 (+)与left join 的用法区别


    Oracle 左连接、右连接、全外连接、(+)号详解

    Oracle  外连接 (OUTER JOIN) 分为三种: 左外连接,右外连接,全外连接。left join、right join 和 join 的区别如下:

    • 左外连接(左边的表不加限制)
    • 右外连接(右边的表不加限制)
    • 全外连接(左右两表都不加限制)
    • 连接(左右两表交集)

    对应SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常省略OUTER关键字, 写成:LEFT/RIGHT/FULL JOIN。


    在左连接和右连接时都会以一张表为基础表,另一张表为补充表,基础表的内容会全部显示,然后再加上两张表匹配的内容。 如果基础表的数据在补充表中没有记录, 那么在相关联的结果集行中补充表列显示为空值(NULL)。

    对于外连接, 也可以使用“(+) ”来表示。 关于使用(+)的一些注意事项:

    1. (+)操作符只能出现在 WHERE 子句中,并且不能与 OUTER JOIN 语法同时使用。
    2.  当使用(+)操作符执行外连接时,如果在WHERE子句中包含有多个条件,则必须在所有条件中都包含(+)操作符。
    3. (+)操作符只适用于列,而不能用在表达式上。
    4. (+)操作符不能与 OR 和 IN 操作符一起使用。
    5. (+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。

    开始前,先创建两张表,插入数据便于理解测试:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    CREATE TABLE A (

    id   number,

    name  VARCHAR2(10)

    );

     

    CREATE TABLE B (

    id   number,

    name  VARCHAR2(10)

    );

     

    INSERT INTO A VALUES(1,'A1');

    INSERT INTO A VALUES(1,'A2');

    INSERT INTO A VALUES(2,'B1');

    INSERT INTO A VALUES(3,'C1');

    INSERT INTO A VALUES(4,'D1');

     

    INSERT INTO B VALUES(1,'AA');

    INSERT INTO B VALUES(1,'BB');

    INSERT INTO B VALUES(2,'CC');

    INSERT INTO B VALUES(6,'DD');

    1、左外连接(LEFT OUTER JOIN/ LEFT JOIN)

    LEFT JOIN 是以左表的记录为基础表,右表的记录为补充表,示例中A表可以看成左表,B表可以看成右表,它的结果集是A表中的全部数据,再加上A表和B表匹配后的数据。换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录。A表有B表没有的记录对应的B表列显示为NULL。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    SQL> select * from A a left join B b on a.id = b.id;

     

            ID NAME               ID NAME

    ---------- ---------- ---------- ----------

             1 A2                  1 AA

             1 A1                  1 AA

             1 A2                  1 BB

             1 A1                  1 BB

             2 B1                  2 CC

             4 D1

             3 C1

    用(+)来实现, 这个 + 号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。如果加号写在右表,左表就是全部显示,所以是左连接。

    1

    select * from A a,B b where a.id=b.id(+);

    2、右外连接(RIGHT OUTER JOIN/RIGHT JOIN)

    和LEFT JOIN的结果刚好相反,是以右表(B)为基础的。它的结果集是B表所有记录,再加上A和B匹配后的数据。 A表记录不足的地方均为NULL。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    SQL> select * from A a right join B b on a.id = b.id;

     

            ID NAME               ID NAME

    ---------- ---------- ---------- ----------

             1 A1                  1 BB

             1 A1                  1 AA

             1 A2                  1 BB

             1 A2                  1 AA

             2 B1                  2 CC

                                   6 DD

    用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。如果加号写在左表,右表就是全部显示,所以是右连接。

    1

    select * from A a,B b where a.id(+)=b.id;

    3、全外连接(FULL OUTER JOIN/FULL JOIN)

    左表和右表都不做限制,所有的记录都显示,两表不足的地方均为NULL。 全外连接不支持(+)写法。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    SQL> select * from A a full join B b on a.id = b.id;

     

            ID NAME               ID NAME

    ---------- ---------- ---------- ----------

             1 A1                  1 BB

             1 A1                  1 AA

             1 A2                  1 BB

             1 A2                  1 AA

             2 B1                  2 CC

             3 C1

             4 D1

                                   6 DD

    4、补充

    1

    2

    3

    4

    5

    6

    7

    8

    9

    SQL> select * from A a,B b where a.id = b.id;

     

            ID NAME               ID NAME

    ---------- ---------- ---------- ----------

             1 A1                  1 BB

             1 A1                  1 AA

             1 A2                  1 BB

             1 A2                  1 AA

             2 B1                  2 CC

    1

    2

    3

    4

    5

    6

    7

    8

    9

    SQL> select * from A a join B b on a.id = b.id;

     

            ID NAME               ID NAME

    ---------- ---------- ---------- ----------

             1 A1                  1 BB

             1 A1                  1 AA

             1 A2                  1 BB

             1 A2                  1 AA

             2 B1                  2 CC

    1

    2

    3

    4

    5

    6

    7

    SQL> select * from A a where a.id in (select b.id from B b);

     

            ID NAME

    ---------- ----------

             1 A2

             1 A1

             2 B1

    1

    2

    3

    4

    5

    6

    7

    SQL> select * from A a where exists (select 1 from B b where a.id = b.id);

     

            ID NAME

    ---------- ----------

             1 A2

             1 A1

             2 B1

    5、Oracle中 (+)与left join 的用法区别

    1. (+) 写在 where 后面,不能与 or/in 连用, a表是主表,b表是附属表。

    select * from a,b where a.id=b.id(+);

    2. 左连接写在 from 与where之间,a left join b  on a.id=b.id  :主表a left join 附表b  on 连接条件。

    select * from a left join b on a.id=b.id;

    3.效率上没区别,left join 可读性高、功能更全面、通用性强、而且是新标准,建议使用left join。

    展开全文
  • mysql查询之左连接查询与右连接查询

    千次阅读 2022-05-21 15:18:09
    **左连接说明**:left join 是left outer join的简写,左(外)连接,左表(a_table)的记录将会全部表示出来, 而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。 **右连接说明**:right join...

    左连接称之为左外连接 右连接称之为右外连接 这俩个连接都是属于"外连接"
    左连接关键字:left join 表名 on 条件 / left outer 表名 join on 条件 右连接关键字:right join 表名 on 条件/ right outer 表名 join on 条件
    左连接说明:left join 是left outer join的简写,左(外)连接,左表(a_table)的记录将会全部表示出来, 而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL。
    右连接说明:right join是right outer join的简写,与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL。

    mysql> show tables;
    +----------------+
    | Tables_in_test |
    +----------------+
    | dept           |
    | employee       |
    | salgrade       |
    +----------------+
    3 rows in set (0.01 sec)
    
    mysql> select * from dept;
    +--------+--------+------+
    | deptnu | dname  | addr |
    +--------+--------+------+
    |     10 | 研发部 | 北京 |
    |     20 | 工程部 | 上海 |
    |     30 | 销售部 | 广州 |
    |     40 | 财务部 | 深圳 |
    +--------+--------+------+
    4 rows in set (0.01 sec)
    
    mysql> select * from employee;
    +-------+--------+--------+------+------------+----------+--------+
    | empno | ename  | job    | mgr  | hiredate   | sal      | deptnu |
    +-------+--------+--------+------+------------+----------+--------+
    |  1004 | 猪八戒 | 经理   | 1009 | 2001-04-02 | 29750.00 |     20 |
    |  1006 | 猴子   | 经理   | 1009 | 2011-05-01 | 28500.00 |     30 |
    |  1007 | 张飞   | 经理   | 1009 | 2011-09-01 | 24500.00 |     10 |
    |  1008 | 诸葛亮 | 分析师 | 1004 | 2017-04-19 | 30000.00 |     20 |
    |  1013 | 林俊杰 | 分析师 | 1004 | 2011-12-03 | 30000.00 |     20 |
    |  1002 | 牛魔王 | 销售员 | 1006 | 2018-02-20 | 16000.00 |     30 |
    |  1003 | 程咬金 | 销售员 | 1006 | 2017-02-22 | 12500.00 |     30 |
    |  1005 | 后裔   | 销售员 | 1006 | 2011-09-28 | 12500.00 |     30 |
    |  1010 | 韩信   | 销售员 | 1006 | 2018-09-08 | 15000.00 |     30 |
    |  1012 | 安琪拉 | 文员   | 1006 | 2011-12-03 | 9500.00  |     30 |
    |  1014 | 甄姬   | 文员   | 1007 | 2019-01-23 | 7500.00  |     10 |
    |  1011 | 妲己   | 文员   | 1008 | 2018-05-23 | 11000.00 |     20 |
    |  1001 | 小乔   | 文员   | 1013 | 2018-12-17 | 8000.00  |     20 |
    +-------+--------+--------+------+------------+----------+--------+
    13 rows in set (0.02 sec)
    
    mysql> select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
    +--------+-------+--------+--------+------+------------+----------+--------+
    | dname  | empno | ename  | job    | mgr  | hiredate   | sal      | deptnu |
    +--------+-------+--------+--------+------+------------+----------+--------+
    | 工程部 |  1004 | 猪八戒 | 经理   | 1009 | 2001-04-02 | 29750.00 |     20 |
    | 销售部 |  1006 | 猴子   | 经理   | 1009 | 2011-05-01 | 28500.00 |     30 |
    | 研发部 |  1007 | 张飞   | 经理   | 1009 | 2011-09-01 | 24500.00 |     10 |
    | 工程部 |  1008 | 诸葛亮 | 分析师 | 1004 | 2017-04-19 | 30000.00 |     20 |
    | 工程部 |  1013 | 林俊杰 | 分析师 | 1004 | 2011-12-03 | 30000.00 |     20 |
    | 销售部 |  1002 | 牛魔王 | 销售员 | 1006 | 2018-02-20 | 16000.00 |     30 |
    | 销售部 |  1003 | 程咬金 | 销售员 | 1006 | 2017-02-22 | 12500.00 |     30 |
    | 销售部 |  1005 | 后裔   | 销售员 | 1006 | 2011-09-28 | 12500.00 |     30 |
    | 销售部 |  1010 | 韩信   | 销售员 | 1006 | 2018-09-08 | 15000.00 |     30 |
    | 销售部 |  1012 | 安琪拉 | 文员   | 1006 | 2011-12-03 | 9500.00  |     30 |
    | 研发部 |  1014 | 甄姬   | 文员   | 1007 | 2019-01-23 | 7500.00  |     10 |
    | 工程部 |  1011 | 妲己   | 文员   | 1008 | 2018-05-23 | 11000.00 |     20 |
    | 工程部 |  1001 | 小乔   | 文员   | 1013 | 2018-12-17 | 8000.00  |     20 |
    | 财务部 | NULL  | NULL   | NULL   | NULL | NULL       | NULL     | NULL   |
    +--------+-------+--------+--------+------+------------+----------+--------+
    14 rows in set (0.04 sec)
    
    mysql> select b.dname,a.* from employee a right join dept b on b.deptnu=a.deptnu;
    +--------+-------+--------+--------+------+------------+----------+--------+
    | dname  | empno | ename  | job    | mgr  | hiredate   | sal      | deptnu |
    +--------+-------+--------+--------+------+------------+----------+--------+
    | 工程部 |  1004 | 猪八戒 | 经理   | 1009 | 2001-04-02 | 29750.00 |     20 |
    | 销售部 |  1006 | 猴子   | 经理   | 1009 | 2011-05-01 | 28500.00 |     30 |
    | 研发部 |  1007 | 张飞   | 经理   | 1009 | 2011-09-01 | 24500.00 |     10 |
    | 工程部 |  1008 | 诸葛亮 | 分析师 | 1004 | 2017-04-19 | 30000.00 |     20 |
    | 工程部 |  1013 | 林俊杰 | 分析师 | 1004 | 2011-12-03 | 30000.00 |     20 |
    | 销售部 |  1002 | 牛魔王 | 销售员 | 1006 | 2018-02-20 | 16000.00 |     30 |
    | 销售部 |  1003 | 程咬金 | 销售员 | 1006 | 2017-02-22 | 12500.00 |     30 |
    | 销售部 |  1005 | 后裔   | 销售员 | 1006 | 2011-09-28 | 12500.00 |     30 |
    | 销售部 |  1010 | 韩信   | 销售员 | 1006 | 2018-09-08 | 15000.00 |     30 |
    | 销售部 |  1012 | 安琪拉 | 文员   | 1006 | 2011-12-03 | 9500.00  |     30 |
    | 研发部 |  1014 | 甄姬   | 文员   | 1007 | 2019-01-23 | 7500.00  |     10 |
    | 工程部 |  1011 | 妲己   | 文员   | 1008 | 2018-05-23 | 11000.00 |     20 |
    | 工程部 |  1001 | 小乔   | 文员   | 1013 | 2018-12-17 | 8000.00  |     20 |
    | 财务部 | NULL  | NULL   | NULL   | NULL | NULL       | NULL     | NULL   |
    +--------+-------+--------+--------+------+------------+----------+--------+
    14 rows in set (0.06 sec)
    
    展开全文
  • 我第一反应,左连接肯定不是笛卡尔积啊,左连接是以左表为准,左表有m条记录,则结果集是m条记录(哈哈,如果是你,你是不是也是这样的反映),同事听了,说内连接会是笛卡尔积。在数据库里试验了一下,发现,事实比...

    先简单解释一下笛卡尔积。

    现在,我们有两个集合A和B。

    A = {0,1}     B = {2,3,4}

    集合 A×B 和 B×A的结果集就可以分别表示为以下这种形式:

    A×B = {(0,2),(1,2),(0,3),(1,3),(0,4),(1,4)};

    B×A = {(2,0),(2,1),(3,0),(3,1),(4,0),(4,1)};

    以上A×B和B×A的结果就可以叫做两个集合相乘的‘笛卡尔积’。

    从以上的数据分析我们可以得出以下两点结论:

    1,两个集合相乘,不满足交换率,既 A×B ≠ B×A;

    2,A集合和B集合相乘,包含了集合A中元素和集合B中元素相结合的所有的可能性。既两个集合相乘得到的新集合的元素个数是 A集合的元素个数 × B集合的元素个数;

    MySQL的多表查询(笛卡尔积原理)先确定数据要用到哪些表。

    将多个表先通过笛卡尔积变成一个表。

    然后去除不符合逻辑的数据(根据两个表的关系去掉)。

    最后当做是一个虚拟表一样来加上条件即可。

    数据库表连接数据行匹配时所遵循的算法就是以上提到的笛卡尔积,表与表之间的连接可以看成是在做乘法运算。

    比如现在数据库中有两张表,student表和 student_subject表,如下所示:

    61990dd9a6bb1f3ccb5d65199cfab219.png  

    0918fc74568b2380d3f2fb6c17cd7600.png

    我们执行以下的sql语句,只是纯粹的进行表连接。

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    看一下执行结果:

    641dad8f3a6e73492312e5f71ae47f30.png  

    353a481fb5721661ed8435167a7633f6.png

    表1.0                            表1.1

    从执行结果上来看,结果符合我们以上提出的两点结论(红线标注部分);

    以第一条sql语句为例我们来看一下他的执行流程,

    1,from语句把student表 和 student_subject表从数据库文件加载到内存中。

    2,join语句相当于对两张表做了乘法运算,把student表中的每一行记录按照顺序和student_subject表中记录依次匹配。

    3,匹配完成后,我们得到了一张有 (student中记录数 × student_subject表中记录数)条的临时表。 在内存中形成的临时表如表1.0所示。我们又把内存中表1.0所示的表称为‘笛卡尔积表’。

    针对以上的理论,我们提出一个问题,难道表连接的时候都要先形成一张笛卡尔积表吗,如果两张表的数据量都比较大的话,那样就会占用很大的内存空间这显然是不合理的。所以,我们在进行表连接查询的时候一般都会使用JOIN xxx ON xxx的语法,ON语句的执行是在JOIN语句之前的,也就是说两张表数据行之间进行匹配的时候,会先判断数据行是否符合ON语句后面的条件,再决定是否JOIN。

    因此,有一个显而易见的SQL优化的方案是,当两张表的数据量比较大,又需要连接查询时,应该使用 FROM table1 JOIN table2 ON xxx的语法,避免使用 FROM table1,table2 WHERE xxx 的语法,因为后者会在内存中先生成一张数据量比较大的笛卡尔积表,增加了内存的开销。

    下面引出Mysql的左右连接和内连接的笛卡尔积...

    一个同事跟我讨论左连接查询,是不是笛卡尔积。我第一反应,左连接肯定不是笛卡尔积啊,左连接是以左表为准,左表有m条记录,则结果集是m条记录(哈哈,如果是你,你是不是也是这样的反映),同事听了,说内连接会是笛卡尔积。在数据库里试验了一下,发现,事实比想象中要复杂。

    首先说下结论:链接查询,如果on条件是非唯一字段,会出现笛卡尔积(局部笛卡尔积);如果on条件是表的唯一字段,则不会出现笛卡尔积。

    下面是具体的试验:(以真三国无双v3.9d蜀国阵容为例...)

    文中会有两张表,user表和job表,表数据如下,其中user为5条记录,job为4条记录

    USER:

    a5de1bebec3c107c8e0a2fcc6996efda.png   job:  

    6cee174454846948940ca14cb9df27a6.png

    1.交叉连接

    如果A表有m(5)条记录,m1条符合on条件,B表有n(4)条记录,有n1条符合on条件,无条件交叉连接的结果为: m*n=5*4=20

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    这种等同于(交叉查询等于不加on的内连接)

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    sql执行结果:总共20条记录

    547523d08d01b46acc1bb7e765250b9a.png

    结论:交叉连接,会产生笛卡尔积。

    2.内连接(可以当做左连接的特殊情况,只保留符合主表中on条件的记录)

    (1)内连接唯一字段

    如果A表有m(5)条记录,m1(4)条符合on条件,B表有n(4)条记录,有n1(3)条符合on条件,内连接唯一字段结果为:Max(m1,n1)=4

    1,2,2,6,7 和 1,2,7,8对比,以user表为主表,因为主表中有4条符合条件的记录(1,2,2,7),而job表有3条符合条件的记录(1,2,7),取两者中的最大的,所以为4条

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    sql执行结果为:4条记录

    13644cf9703d7232a1c1c0c5046d90a6.png

    结论:假如,内连接查询,on条件是A表或者B表的唯一字段,则结果集是两表的交集,不是笛卡尔积。

    (2)内连接非唯一字段

    如果A表有m(5)条记录,m1(2)条符合on条件,B表有n(4)条记录,有n1(3)条符合on条件,则结果集是Max(m1,n1)=3条

    1,2,2,6,7 和 1,1,7,8对比,以user表为主表,因为主表中有2条符合条件的记录(1,7),而job表有3条符合条件的记录(1,1,7),取两者中的最大的,所以为3条

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    f2dcf7230270a29a45612afd3da7b09c.png

    结论:假如,on条件是表中非唯一字段,则结果集是两表匹配到的结果集的笛卡尔积(局部笛卡尔积) 。

    3.外连接

    (1)左连接

    a.左连接唯一字段

    假如A表有m(5)条记录,B表有n(4)条记录,则结果集是m=5

    1,2,2,6,7 和 1,2,7,8对比,以user表为主表,因为主表中有4条符合条件的记录(1,2,2,7),而job表有3条符合条件的记录(1,2,7),取两者中的最大的,所以取4条,然后再加上user表中没有在job表中找到对应关系的记录(即对应的job表都为null,5-4=1),所以最终结果为4+1=5条

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    SQL查询结果:5条记录

    ed8c0f6facb0e17dde07d5d20509dccf.png

    结论:on条件是唯一字段,则结果集是左表记录的数量。

    b.左连接非唯一字段

    1,2,2,6,7 和 1,1,7,8对比,以user表为主表,因为主表中有2条符合条件的记录(1,7),而job表有3条符合条件的记录(1,1,7),取两者中的最大的,所以取3条,然后在加上user表在job表中没有匹配的记录(即对应的job表都为null,为5-2=3),所以最终结果为3+3=6条

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    fa5ac13f4294a1600f4380ddfe232d31.png

    结论:左连接非唯一字段,是局部笛卡尔积。

    c.当on 条件为假时的内连接:

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    sql查询结果:5条

    6f0e9642005c17b55b393befa4d73eff.png

    结论:当on条件为假的时候,即user在job表中一条符合记录的都没有,那么即为:user表中的所有记录条数,所以为5条,job表中的值都为null

    (2)右连接

    同左连接,这里就不赘述了

    全外连接

    mysql不支持

    总结:左右连接是否产生笛卡尔积,和on的条件是否为唯一索引没有关系,只和左表、右表两者各自匹配on条件的记录条数有关系(左连接和右连接可以这么做:1:由INNER JOIN查询全匹配记录;2:查询左表或者右表没有符合on条件的记录;3.全匹配记录+没有匹配上的记录就是左连接或者右连接查询的结果集)

    1.全匹配:

    无论哪种查询,首先计算出on匹配记录(FROM user INNER JOIN job ON ...或者使用 FROM user,job where...),匹配记录的查询结果为:若A表有m条记录,符合on查询条件的为m1条,B表有n条记录,符合on条件的为n1条,那么匹配记录为MAX(m1,n1);

    2.左连接:

    结果集为:MAX(m1,n1)+(m-m1);

    如果m1 > n1,则不会产生笛卡尔积,因为无论不匹配的记录(m-m1),还是匹配的记录MAX(m1,n1),都是从左表中取记录,所以不会出现重复的记录;反之,如果m1 < n1,则一定会产生笛卡尔积,因为MAX(m1,n1)是从右表中取的,而根据笛卡尔积的原理,右表中的每条记录都会和左表中的所有记录匹配一次,所以符合on条件的n1条记录也一定会和左表中的所有记录都匹配一次,而左表中符合记录只有m1条,所以造成笛卡尔积的条数为(n1-m1)条

    即用内连接的记录(MAX(m1,n1)),加上左表没有满足on条件的记录(m-m1),所以为:MAX(m1,n1)+(m-m1);

    3.有连接

    结果集为:MAX(m1,n1)+(n-n1);

    如果m1 n1,则一定会产生笛卡尔积,因为MAX(m1,n1)是从左表中取的,所以造成笛卡尔积的记录条数为(m1-n1)条

    即用内连接的记录(MAX(m1,n1)),加上右表没有满足on条件的记录(n-n1),所以为:MAX(m1,n1)+(n-n1);

    下面再来谈下:

    Mysql:ON 与 WHERE 的区别

    很多同学在学习 Mysql 表关联的时候弄不清 ON 与 WHERE 的区别,不知道条件应该写在 ON 里面还是 WHERE 里面,作者在工作的时候也入过坑,总觉得条件写在哪里查询结果都是一样的,最后出错坏了事,差点惹了大祸。所以今天简单易懂的总结一下他们的区别,大家共同学习。

    准备工作

    我们先准备两个表,并造一些数据:

    表t1:

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    表t2:

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    查询结果如图:

    表t1记录:

    720068a4eb6c87a049c27d06fb3f1729.png

    表t2记录:

    df946694c28e674a3744a75f7e46036b.png

    探究

    口诀:先执行 ON,后执行 WHERE;ON 是建立关联关系,WHERE 是对关联关系的筛选。

    记住这句话就可以准确地判断查询结果了,我们通过两个 sql 来进行分析:

    SQL1:

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    前提是 LEFT JOIN,所以左边的数据在创建关联关系时会保留,根据口诀,先执行 ON 建立关联关系,形成子表,最后在子表中通过 WHERE 筛选,过程如下:

    左表符合记录的t1.id = t2.id的记录有2条,右表符合记录的有4条,所以MAX(m1,n1)为4条,其中左表没有符合on条件的记录为(3-2=1)条,所以LEFT JOIN的结果总共有5条,最后一条左表没有匹配上右表记录,所以右表的属性都为null,如下:

    15e727cc7dad02edb5c7f209199764f4.png

    但是最终结果从5条记录中再通过where进行筛选,即matches为2,所以结果只有2条(注意先LEFT JOIN,然后再是where,所以此时5条记录中不符合where条件的记录会被排除,即最终的结果不再是左表所有的记录):

    2574ccffa5e6e98d4b7779ed49650f78.png

    SQL2:

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    SQL2没有 WHERE,那么 ON 建立的关联关系就是最终结果(因为没有where条件进行最终筛选,所有最终结果为内联记录加上左表中没有符合on条件的记录):

    符合ON条件的记录,改为内联INNER JOIN ,查询基础数据:MAX(m1,n1)

    当前内容已被隐藏,您需要登录才能查看快速登录快速注册

    所以MAX(m1,n1)为2条,结果为:

    18836162d747af5e0bf5091fac200426.png

    再由基础数据加上左表没有匹配上的记录数(只有id为3的没有匹配上,即(n-n1) = 1)只有1条,所以最终结果为:

    最终结果为:MAX(m1,n1)+(m-m1) = 2 + (id为3的记录) = 3条

    12aa14b465f66372c38a1c1ea34f98ea.png

    通过这两个 sql 可以很好的区分 WHERE 和 ON 的区别了,希望大家使用的时候多注意这一点,避免犯错!

    展开全文
  • mysql全连接、左连接与右连接
  • SQL内连接、左连接、右连接的区别

    千次阅读 2022-03-22 16:29:48
    SQL内、、右连接之间的区别。通过实例对比,防止单纯的理解上存在的误区。
  • 左连接 :left join 右外连接 right outer join 右连接: right join 全连接 full join 、union 准备 现在有2张表,A表和B表,数据和表结构如下 内连接 内连接查询的是两张表的并集,也就是A表和B表都必须有数据...
  • Mysql—— 内连接、左连接、右连接以及全连接查询

    万次阅读 多人点赞 2018-10-05 23:03:31
    一、内连接查询 inner join 关键字:inner join on 语句:select * from a_table a inner join b_table b on a.a_id = b.b_id; 说明:组合两个表中的记录,返回关联字段相符的记录,也就是返回两个表的交集...
  • Linq左连接

    千次阅读 2022-06-15 11:26:09
    Linq左连接
  • MySQL 左连接、右连接、内连接

    千次阅读 2021-08-17 21:51:01
    左连接,以左表为参照,显示所有数据,右表中没有则以null显示 右连接,以右表为参照显示数据,左表中没有则以null显示 左连接where只影向右表,右连接where只影响左表。 一、内连接查询 inner join 关键字..
  • 连表总结 什么是连接表? 多表查询原理:将多个表通过笛卡尔积形成...left join : 左连接,返回左表中所有的记录以及右表中连接字段相等的记录。 right join : 右连接,返回右表中所有的记录以及左表中连接字段相等的
  • 数据库左连接和左外连接有区别吗

    千次阅读 2021-01-20 02:28:13
    2016-12-15 回答简单来讲,随便来个例子:a表 b表id name id name1 a 1 b2 b 3 c4 c内连接就是表和右表相同的数据:select * from a i...
  • 1、左连接查询 进行左连接查询时,可以查询出表名1所指的表中的所有记录。而表名2所指的表中,只能查询出匹配的记录select * fromemployee;select * fromdepartment;select num,name,employee.d_id,age,sex,d_name,...
  • MYSQL 左连接与右连接

    千次阅读 2021-01-18 19:14:13
    一、 LEFT JOINLEFT JOIN 关键字从表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。语法:SELECT column_name(s)FROM table1LEFT JOIN table2ON table1.column_name=...
  • MySQL 左连接 右连接 详解

    千次阅读 2021-01-26 04:21:01
    5 行) 结果说明: left join是以A表的记录为基础的,A可以看成表,B可以看成右表,left join是以表为准的. 换句话说,表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID)...
  • 什么是外连接,和内连接有什么区别?2. 外连接的分类2.1 **案例:** 找出每个员工的上级领导(所有员工必须查询出来)2.2 案例2:找出哪个部门没有员工? 1. 什么是外连接,和内连接有什么区别? 内连接: 假设A和B...
  • 一、交叉连接(cross join)交叉连接(cross join):有两种,显式的和隐式的,不带on子句,返回的是两表的乘积,也叫笛卡尔积。例如:下面的语句1和语句2的结果是相同的。语句1:隐式的交叉连接,没有cross join。...
  • Mysql内连接、左连接、右连接区别-理解记忆背景说明唠叨一下说个前置第一点、说一下内连接合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个...
  • 连接包括三种,分别是连接、右外连接、全外连接。. 对应的sql关键字:LEFT/RIGHT/FULL OUTER JOIN,通常我们都省略OUTER关键字,写成LEFT/RIGHT/FULL JOIN。. 在、右外连接中都会以一种表为基表,基表的所有行...
  • sql的内连接、左连接、右连接

    千次阅读 2021-11-03 13:51:36
    连接是两个表中都必须有连接字段的对应值的记录,数据才能检索出来。 语法:select 字段 from 表1 inner join 表2on 条件 select * from 表1,表2where条件 from后面直接写两个表名,这样写等价于内连接 如果不写...
  • 数据库左连接和右连接有什么区别

    千次阅读 2021-01-26 03:10:25
    数据库中的左连接和右连接的区别可以概括为一句话来表示即左连接where只影响右表,右连接where只影响到左表【推荐课程:MySQL教程】数据库中的左连接(left join)和右连接(right join)区别左连接(Left Join)select * ...
  • 知识点 左连接、右连接、内连接

    千次阅读 2021-03-17 10:08:52
    左连接: 左表的所有行会显示,右表的 只有和左表匹配到的行才会显示。即: A表的全集+ AB表的交集 右连接: 右表的所有行会显示,左表的 只有和右表匹配到的行才会显示。 即:B表的全集+AB表的交集 全连接: ...
  • 【mysql 优化 5】左连接和右连接优化

    千次阅读 2021-01-19 11:48:57
    mysql以下列方式实现一个A left join B 连接条件:1,表B设置为依赖于表A和A所依赖的所有表2,表A设置为依赖使用left join条件的所有表(除了B)3,left join条件被用于决定如何从表B中取数据行(换句话说,不使用WHERE...
  • Oracle左连接返回多条记录中一条记录的查询语句,更具指定条件分组排序,返回各组中第一条记录
  • 左连接 ,右连接,内连接和全外连接的4者区别

    万次阅读 多人点赞 2018-07-24 22:36:02
     left join (左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。  right join (右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。  inner join (等值连接或者叫内连接):只...
  • 我们今天来学习一下sql语句中的左连接右连接以及自然连接,先说结论: 左连接:以左表为主,显示左表所有的数据,右表中没有的显示null值。 右连接:以右表为主,显示右表所有的数据,左表中没有的显示null值. 内...
  • 左右连接和内连接的区别

    千次阅读 2021-11-14 09:23:22
    左连接:在 LEFT JOIN 左边的表里面数据全被全部查出来,右边的数据只会查出符合ON后面的符合条件的数据,不符合的会用NULL代替。 (2)右连接查询: 右连接:与 LEFT JOIN 正好相反,右边的数据会会全部查出来,...
  • SQL(左连接,右连接,内连接)

    千次阅读 2021-10-13 22:01:57
    左连接(Left Join):多表拼接时,以左边的表为基准,右边未匹配的值会显示为空(Null/None)。 案例: select * from employees a left join salaries b on a.emp_no=b.emp_no 2 右连接(Right Join) 右连接...
  • 1.外连接–左连接结果table1居左,故谓之左连接。这种情况下,以table1为主,即table1中的所有记录均会被列出。有一下三种情况:一个。对于table1中的每一条记录对应的城市如果在table2中也恰好存在而且刚好只有一条...
  • Mysql中外连接,内连接,左连接,右连接的区别

    千次阅读 多人点赞 2020-09-16 16:00:14
    外连接2.1左连接2.2右连接3. 内连接 1. 前言 相信大家一定都做过多表的连表查询,并且这其中的查询方式也比较多样. 可能主要就是下面这几种方式: 直接通过where语句将重叠的字段进行匹配就比如下面这种 select *...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 948,503
精华内容 379,401
关键字:

左链接

友情链接: progress-2.zip