zoukankan      html  css  js  c++  java
  • 在mysql中同时使用left join on 和where 的查询结果分析

    以前用惯了oracle,在处理左连接和有链接的时候,只需要在sql中添加(+)就可以了,但是在mysql中,将left join或者right join 与 on 和 where进行联合使用的时候,不同的联合用法,得到的却是不同的结果。现在记录一下。

    假设有左表tb_oder,该表有order_id和user_id字段;有右表tb_user,该表有user_id和user_name两个字段,两个表使用user_id进行关联。

    SQL1:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id;
    这是最常规的用法,如果右表中没有对应的数据,则结果集中显示为空。

    SQL2:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id
    and u.user_id > 10;
    这个对右表进行筛选之后再与左表关联的,所以,即便右表和左表中都有user_id<10的数据,user_name的显示结果也为空。

    SQL3
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id
    and o.order_id > 10;

    SQL4:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id
    and o.user_id > 10;
    这两个语句貌似是对左表进行筛选之后,再与右表关联,但是他并不是这样的。实际上,无论如何,左表tb_order中的数据都会全部显示,对左表进行限定的条件下,对应的右表中符合关联条件的内容却被强制设置为空。这两个语句的效果与SQL2是一样的,但是效果却难以理解,一般不建议这么写。

    SQL5:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id
    where u.user_id > 10;

    SQL6:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from tb_order o LEFT JOIN tb_user u
    on o.user_id = u.user_id
    where o.user_id > 10;
    这两个语句的结果更有意思,他们的效果是一样的,就是,把使用left join on 进行关联的结果集再按照where条件进行筛选。

    按照上面的分析,似乎,这样的SQL中,并无一个比较易懂的,首先去筛选左表的内容,然后再与右表进行匹配的办法。较好的办法就是,对左表用子查询进行筛选,如果无法理解上面的left join on where 中的where的使用方式,也可以对右表用子查询进行筛选。
    SQL如下:
    select o.order_id,o.user_id,u.user_id,u.user_name
    from ( select * from tb_order where order_id > 10 ) o LEFT JOIN tb_user u
    on o.user_id = u.user_id;

    select o.order_id,o.user_id,u.user_id,u.user_name
    from ( select * from tb_order where order_id > 10 ) o LEFT JOIN (select * from tb_user where user_id > 20) u
    on o.user_id = u.user_id;
  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/babyha/p/13932348.html
Copyright © 2011-2022 走看看