表链接(jion)

今天落入的join的陷阱,其实这是迟早的事,应为只知道人云亦云的写着自认为很熟悉的SQL语句,但这些SQL语句是怎么执行的、on和where在什么时候起作用,怎么过滤等等一些深入的机制根本不了解,所以落入陷阱是迟早的事。

现场还原:有两个表A、B存储网站订单相关的日志信息,关联字段为A.ID=B.ORDERID。我想以A表为主,做左联接查询某一天的订单信息。假如日期是2014-12-02

首先:查询了A表当天的数据量

select count(distinct A.ID) from  A where A.dt='2014-12-02'

输出:123534

查询了B表当天的记录数

select count(distinct B.ORDERID) fromB whereB.dt='2014-12-02'

输出:2780

然后:以A表为主做左联接:

select count(*) from A left join B on A.ID = B.ORDERID where A.dt='2014-12-02' and B.dt='2014-12-02';-----------------(1)

输出:2780


这是为什么呢?曾经当我几番周折终于记下“左联接就是以左边为准,左边的记录都会出现的在结果集中,右表没有对应项时补null,右联接就是以右表为准,右表的记录都会出现,坐表没有对应记录时补null” 时,我以为我懂里jion,可面对这结果我又无法解释了,甚至怀疑上句准则对么??

又是几番周折后,终于弄清原因了,引用其他博文的一句话:ON是用来定义连接条件的,WHERE用来过滤结果集

所以当执行:

select count(*) from A left join B on A.ID = B.ORDERID where A.dt='2014-12-02';-------------(2)

输出:123534

此时A的记录全部出现,而没有联上B的记录相应的列为NULL,这部分有123534 - 2780,

当加上过滤条件 B.dt='2014-12-02' 后,在语句(2)的结果集中由进行了一次过滤,把123534条记录中B.dt != '2014-12-02' 的记录全部过滤掉了,当然包括哪些为NULL的记录,所以最后就只剩下能关联上B表的2780条记录了。

那我们如何实现我们的初始逻辑呢,及选出2014-12-02这一天的A表和B表的数据,做个连接呢。

我们应当将约束条件B.dt='2014-12-02' 写在on后

select count(*) from A left join B on A.ID = B.ORDERID and B.dt='2014-12-02'  where A.dt='2014-12-02';

输出:123534

过滤条件的位置可不能乱加啊....


补充:一下内容来自:http://blog.csdn.net/shangboerds/article/details/5213264

第一:SQL语句执行的顺序

  1. FROM
  2. JOIN ON
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. SELECT
  7. ORDER BY
  8. FETCH FIRST

第二:ON 和 WHERE 的区别:ON是用来定义连接条件的,WHERE用来过滤结果集

参考:

http://www.cnblogs.com/alexlo/archive/2012/11/16/2773257.html

http://blog.csdn.net/shangboerds/article/details/5213264

http://blog.csdn.net/jiuqiyuliang/article/details/10474221

后记:

SQL的深入运行机制还有待进一步深入....


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值