精华内容
下载资源
问答
  • 数据库left join

    2013-03-22 23:26:35
    left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的。换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID)。B表记录不足的...
    left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的。换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID)。B表记录不足的地方均为NULL。
    展开全文
  • Left join , Right Join, Inner Join 的相关内容,非常实用
  • c.id left join county_seat cs on ra.area = cs.id left join country ct on ra.country = ct.id where ra.states = :1 and ra.providerid = :2 order by ra.is_default asc, ra.update_time desc
  • 第三是left join,right join,inner join中的小表驱动大表的疑问。 left join的作用 作用:返回包括左表中的所有记录和右表中联结字段相等的记录。 下面通过例子来说明。 假设表1为: +----+------+ | id ...

    前言

    记录三个东西,
    第一是left join的作用,
    第二是left join中on和where的区别,
    第三是left join,right join,inner join中的小表驱动大表的疑问。

    left join的作用

    作用:返回包括左表中的所有记录和右表中联结字段相等的记录。

    下面通过例子来说明。

    假设表1为:

    +----+------+
    | id | name |
    +----+------+
    |  1 | a    |
    |  2 | b    |
    |  3 | c    |
    +----+------+

    表2为:

    +----+------+
    | id | name |
    +----+------+
    |  3 | c    |
    |  4 | d    |
    |  5 | c    |
    +----+------+

    例如:

    select t1.*,t2.* from t1 left join t2 on t1.name=t2.name;

    其中过程是怎样的?
    我的理解:数据库会先取得表1的全部记录,对每条记录再用表2的每条记录根据on条件进行匹配(也就是说这里是两层循环),
    若匹配上得,则拼接这两个记录作为结果集的一部分,
    若表2没有任何一条记录满足on条件,则保留表1的记录,表2的记录则以null补上再作为结果集的一部分,
    最后从结果集中选择需要的字段部分作为最终的结果集。

    因此最终输出的结果是:

    +----+------+------+------+
    | id | name | id   | name |
    +----+------+------+------+
    |  3 | c    |    3 | c    |
    |  3 | c    |    5 | c    |
    |  1 | a    | NULL | NULL |
    |  2 | b    | NULL | NULL |
    +----+------+------+------+

    left join中on和where的区别

    然后是另一个问题,on和where的问题。基于上面的select语句,如果我们只想保留t1.id>2的记录,这样写的话:

     select t1.*,t2.* from t1 left join t2 on t1.name =t2.name and t1.id>2;

    输出的结果是:

    +----+------+------+------+
    | id | name | id   | name |
    +----+------+------+------+
    |  3 | c    |    3 | c    |
    |  3 | c    |    5 | c    |
    |  1 | a    | NULL | NULL |
    |  2 | b    | NULL | NULL |
    +----+------+------+------+

    也就是说,on条件中的t1.id>2没有起作用。

    这是为什么呢?

    结论是这样的:on后面带的条件是作用于附表的,也就是说on后面带的条件是当表1的记录与表2的记录匹配时,作为表2的匹配条件。

    举例来说:
    当用表1的第3条(3,c)记录与表2的每条记录{(3,c),(4,d),(5,c)}进行匹配时,
    假设on条件是只是t1.name =t2.name时,
    当表1的(3,c)这条记录
    与表2的(3,c)进行匹配时,对表2这条记录而言,on条件成立,(3,c,3,c)作为结果集,
    与表2的(4,d)进行匹配时,对表2这条记录而言,on条件不成立,不处理,
    与表2的(5,c)进行匹配时,对表2这条记录而言,on条件不成立,不处理。

    当on条件是t1.name =t2.name and t1.id>2时,
    当表1的(3,c)这条记录
    与表2的(3,c)进行匹配时,对表2这条记录而言,on条件是t1.id>2成立,(3,c,3,c)作为结果集的一部分,
    与表2的(4,d)进行匹配时,对表2这条记录而言,on条件不成立,不处理,
    与表2的(5,c)进行匹配时,对表2这条记录而言,on条件不成立,不处理。
    也就是说,on条件只有作用于附表(此例子中指表2)的字段时才是有效的。

    因此,如果要保留t1.id>2的记录,应通过where关键字来实现:

    select t1.*,t2.* from t1 left join t2 on t1.name =t2.name where t2.id>2;

    输出结果为:

    +----+------+------+------+
    | id | name | id   | name |
    +----+------+------+------+
    |  3 | c    |    3 | c    |
    |  3 | c    |    5 | c    |
    +----+------+------+------+

    on条件不能对附表进行完全过滤。

    假如输入的是:

    select t1.*,t2.* from t1 left join t2 on t1.name =t2.name and t2.id>3;

    照理说,输出的记录中,t2.id都得大于3。可实际呢,输出结果为:

    +----+------+------+------+
    | id | name | id   | name |
    +----+------+------+------+
    |  3 | c    |    5 | c    |
    |  1 | a    | NULL | NULL |
    |  2 | b    | NULL | NULL |
    +----+------+------+------+

    为什么输出的记录中有t2.id为NULL的呢?

    我们再用前面的那种方式进行分析:
    当用表1的第3条(1,a)记录与表2的每条记录{(3,c),(4,d),(5,c)}进行匹配时,
    假设on条件是只是t1.name =t2.name and t2.id>3,
    当表1的(1,a)这条记录
    与表2的(3,c)进行匹配时,对表2这条记录而言,on条件不成立,不处理,
    与表2的(4,d)进行匹配时,对表2这条记录而言,on条件不成立,不处理,
    与表2的(5,c)进行匹配时,对表2这条记录而言,on条件不成立,不处理。
    然后,由于表2中没有一条记录能与表1的这条记录匹配。因此,会保留表1的这条记录并以表2的记录为NULL来进行拼接。
    因此,(1,a,NULL,NULL)也作为结果集的一部分。

    因此,这里并不是on条件的t2.id>3没有生效,而是on条件不能对附表进行完全过滤。
    要想达到输出的结果满足t2.id>3,可以通过where来实现。

    on条件,通常是用来使用主表的字段信息来结果附表进行过滤的。也就是说,on条件,通常是这样的:t1.xx=t2.xxx。即用到了两表的字段信息。

    小表驱动大表

    结论:小表驱动大表,查找效率会高很多。反之,效率会很低。我们应让小表作为驱动表。

    大跟小描述的是表的记录行数以及字段数量。

    小表驱动大表涉及的是效率的问题。

    left join中,前表(左表)是主表,也是驱动表。如果前表是大表,后表是小表,就成了大表驱动小表,效率较低。
    right join中,后表(右表)是主表,也是驱动表。如果后表是大表,前表示小表,也是大表驱动小表,效率较低。
    而inner join,会自动选择小表作为驱动表。

    当假如a表存的是某大型公司的员工信息表,b表存的是部门信息表。那么很明显,a表就是大表了,b表就是小表了。

    疑问:就算我知道left join中前表是大表,又能怎么办?如果我要的就是left join的效果呢?换成right join输出的数据就不一样了啊。

    在网上查了许多小表驱动大表的问题,有些感觉写得很扯。所有现在我也只是知道这个结论,但是这个结论怎么来的,我也没想懂。即使知道MySQL表关联的算法是Nest Loop Join,是通过驱动表的结果集作为循环基础数据,然后一条一条地通过该结果集中的数据作为过滤条件到下一个表中查询数据,然后合并结果。

    如懂这一块的,望能分享之。

    小表驱动大表相关文章:
    http://blog.csdn.net/codejas/article/details/78632883
    http://blog.csdn.net/u013065023/article/details/54964275
    https://www.cnblogs.com/zhengyun_ustc/p/slowquery1.html
    http://blog.itpub.net/22664653/viewspace-1692317/
    https://www.cnblogs.com/softidea/p/6409443.html

    展开全文
  • left join,right join,inner join,full join之间的区别 </h2> <div class="postbody"> 参考 https://www.cnblogs.com/assasion/p/7768931.html ...sql中的连接查询有inner join(内连接)、left...

    left join,right join,inner join,full join之间的区别
        </h2>
        <div class="postbody">
    

    参考

    https://www.cnblogs.com/assasion/p/7768931.html

    https://blog.csdn.net/rongbo_j/article/details/46352337

    sql中的连接查询有inner join(内连接)、left join(左连接)、right join(右连接)、full join(全连接)四种方式,它们之间其实并没有太大区别,仅仅是查询出来的结果有所不同。
    例如我们有两张表:
    这里写图片描述

    Orders表通过外键Id_P和Persons表进行关联。

    1.inner join(内连接),在两张表进行连接查询时,只保留两张表中完全匹配的结果集。

    我们使用inner join对两张表进行连接查询,sql如下:

    SELECT p.LastName, p.FirstName, o.OrderNo
    FROM Persons p
    INNER JOIN Orders o
    ON p.Id_P=o.Id_P and 1=1  --用and连接多个条件
    ORDER BY p.LastName

    查询结果集:
    这里写图片描述

    此种连接方式Orders表中Id_P字段在Persons表中找不到匹配的,则不会列出来。

    注意:单纯的select * from a,b是笛卡尔乘积。比如a表有5条数据,b表有3条数据,那么最后的结果有5*3=15条数据。

    但是如果对两个表进行关联:select * from a,b where a.id = b.id 意思就变了,此时就等价于:

    select * from a inner join b on a.id = b.id。即就是内连接。

    但是这种写法并不符合规范,可能只对某些数据库管用,如sqlserver。推荐最好不要这样写。最好写成inner join的写法。

     

    内连接查询 (select * from a join b on a.id = b.id) 与 关联查询 (select * from a , b where a.id = b.id)的区别

     

    2.left join,在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。

    我们使用left join对两张表进行连接查询,sql如下:

    SELECT p.LastName, p.FirstName, o.OrderNo
    FROM Persons p
    LEFT JOIN Orders o
    ON p.Id_P=o.Id_P
    ORDER BY p.LastName

    查询结果如下:
    这里写图片描述
    可以看到,左表(Persons表)中LastName为Bush的行的Id_P字段在右表(Orders表)中没有匹配,但查询结果仍然保留该行。

    3.right join,在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。

    我们使用right join对两张表进行连接查询,sql如下:

    SELECT p.LastName, p.FirstName, o.OrderNo
    FROM Persons p
    RIGHT JOIN Orders o
    ON p.Id_P=o.Id_P
    ORDER BY p.LastName

    查询结果如下:

    这里写图片描述
    Orders表中最后一条记录Id_P字段值为65,在左表中没有记录与之匹配,但依然保留。

    4.full join,在两张表进行连接查询时,返回左表和右表中所有没有匹配的行。

    我们使用full join对两张表进行连接查询,sql如下:

    SELECT p.LastName, p.FirstName, o.OrderNo
    FROM Persons p
    FULL JOIN Orders o
    ON p.Id_P=o.Id_P
    ORDER BY p.LastName

    查询结果如下:
    这里写图片描述
    查询结果是left join和right join的并集。

    这些连接查询的区别也仅此而已。

            </div>
    

     

    分类: sql
    展开全文
  • TiDB集群left join及版本问题 ...

           TiDB集群left join及版本问题

                                                                                                            2019-08-14 刘春雷

    1、汇总

    1.1、情况

    TiDB某集群版本  2.1.2   ,升级至  3.0.1 ,升级无报错

    问题:升级后,业务反应:报表平台部分任务执行失败

    1.2、问题及解决

    问题原因 2.1.2 版本 升级至 3.0.1   版本 后,多于 2个   left join  的SQL执行报错: ERROR 1105 (HY000): Column xxx . xxx   is ambiguous

    测试:  多个inner join无影响

    处理: 升级至 3.0.2  解决

    注:希望3.0.1 版本的TiDB小伙伴,如果有偏复杂的left  join 场景,要及时升级至3.0.2版本

    感谢TiDB官方小伙伴的及时支持,点赞~

    2、复现问题

    2.1、具体复现

    CREATE TABLE `lcl_test` (
    `id` int(11) DEFAULT NULL,
    `name2` varchar(10) DEFAULT NULL
    ) ENGINE=InnoDB ;

    insert into lcl_test values (1,'a');

    insert into lcl_test values (2,'b');

    insert into lcl_test values (3,'c')

    【查询SQL】

    select  t.id  from
    (select id from lcl_test ) t
    left join 
    (select id from lcl_test ) t1
    on  t.id = t1.id
    left join
    (select id from lcl_test ) t2
    on  t.id = t2.id
    left join
    (select id from lcl_test ) t3
    on  t.id = t3.id
    left join
    (select id from lcl_test ) t4
    on  t.id = t4.id ;

    【2.1.0.rc2版本,执行正常】

    【mysql5.6版本,执行正常】

    【3.0.1版本,多于2个left join执行报错】

    【3.0.1 版本 ,left join 个数测试,测试2个left join 可以执行,多余2个,报错】

    【3.0.1  版本,多个inner join测试,正常执行】

    3、处理

    3.1、具体处理

    升级至 3.0.2  版本 完成

    3.2、测试

    【3.0.2 版本测试,可以正常执行】



    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28823725/viewspace-2653742/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/28823725/viewspace-2653742/

    展开全文
  • 注意:select * from table1 a inner join table2 b on a.city = b.city 和select * from table1 a join table2 b on a.city = b.city 的效果是一样的,即如果join的左边没有诸如left、right或者inner这样的关键字时...
  • Left Join / Right Join /inner join相关 关于左连接和右连接总结性的一句话: 左连接where只影向右表,右连接where只影响左表。 Left Join select * from tbl1 Left Join tbl2 where tbl1.ID = tbl2.ID...
  • 我没去理解+,记住也忘记了。还是用标准sql好些。也便于别人理解。看这篇帖子。...对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将...
  • 求教大神,看mysql执行的解释感觉没什么区别,但是STRAIGHT_JOIN执行sql只需0.2秒,用left join却需要七秒,截图如下,第一张是STRAIGHT_JOIN ![图片说明]...
  • 我使用的是mysql数据库
  • 一.先看一些最简单的例子 例子 Table A aid adate 1 a1 2 a2 3 a3 TableB bid bdate ...select * from a inner join b on a.aid = b.bid这是仅取出匹配的数据. 此时的取出的是: 1 a1 b1
  • 上一篇对三个join的语句做了一个区别,如果连最基础的都不清楚,那么请先参考:inner joinleft join 和right join之间的区别 碰巧在项目中遇到了一个sql,是left join和where的条件限制的区别,想了好半天,...
  • Oracle数据库 Left Join 使用之我见

    千次阅读 2012-04-16 21:24:16
    在Oracle 9i数据库中使用LEFT JOIN这种连表查询方式的效率是极为低下的。 在项目中使用了这么一条语句: select tmp2.company_name,sum(tmp2.radio_send_bytes + tmp2.radio_recv_bytes)/(1024*1024*1024) as ...
  • left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的.  换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID). B表记录不足的...
  • 需要跨数据库left join 俩个表a,b。。数据库是不同类型的数据库oracle,mssql select * from a left join b on a.id=b.id where b.col1="xxx" 和 select * from a left join b on a.id=b.id where a.col1="ccc" ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,311
精华内容 1,324
关键字:

数据库leftjoin