表链接(jion)

来源:互联网 发布:js获取class个数 编辑:程序博客网 时间:2024/04/29 19:45

今天落入的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
原创粉丝点击