[分享] 浅析SQL语句中的JOIN_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2457 | 回复: 0   主题: [分享] 浅析SQL语句中的JOIN        下一篇 
i1314lovejoy
注册用户
等级:少校
经验:1234
发帖:69
精华:0
注册:2015-7-14
状态:离线
发送短消息息给i1314lovejoy 加好友    发送短消息息给i1314lovejoy 发消息
发表于: IP:您无权察看 2015-8-13 21:05:10 | [全部帖] [楼主帖] 楼主

开门见山,联表运算的逻辑查询处理流程几个阶段如下图:

北京联动北方科技有限公司

STEP 1:首先参与联接的两表(不论是外联还是内联)会进行笛卡尔积运算,生成虚拟表TEMP1

STEP 2:TABLE TEMP1进入 ON筛选阶段,只会保留TEMP1中ON条件为TRUE的的结果并生成虚拟表TEMP2

这里需要注意的是 如果是外联接,此时保留表中不符合ON条件的条目也被剔除了!

     (A LEFT JOIN B,A就是保留表。A FULL JOIN B,AB都是保留表)

如果是内联接,JOIN流程已经走完,将进入WHERE流程。

            如果是外联接,还有STEP 3

STEP 3:如果是外联接,此时需要将保留表中不符合ON条件的条目加回到TEMP2生成虚拟表TEMP3           

     此时JOIN流程走完,将进入WHERE流程

在此我们新建两张表以方便说明

CREATE TABLE test_Customers
(
customerid CHAR(5)     NOT NULL  PRIMARY KEY,
city       VARCHAR(10) NOT NULL
);
CREATE TABLE test_Orders
(
orderid    INT      NOT NULL  PRIMARY KEY,
customerid CHAR(5)  NULL
);
INSERT INTO dbo.test_Customers(customerid, city) VALUES('fissa', 'Madrid');
INSERT INTO dbo.test_Customers(customerid, city) VALUES('frndo', 'Madrid');
INSERT INTO dbo.test_Customers(customerid, city) VALUES('krlos', 'Madrid');
INSERT INTO dbo.test_Customers(customerid, city) VALUES('mrphs', 'Zion');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(1, 'frndo');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(2, 'frndo');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(3, 'krlos');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(4, 'krlos');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(5, 'krlos');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(6, 'mrphs');
INSERT INTO dbo.test_Orders(orderid, customerid) VALUES(7, NULL);


我们来分析下面两句SQL的执行流程:

--SQL1SELECT*FROM test_Customers AS c LEFTJOIN test_Orders AS o ON c.customerid=o.customerid AND orderid=2--SQL2SELECT*FROM test_Customers AS c LEFTJOIN test_Orders AS o ON c.customerid=o.customerid WHERE orderid=2

STEP 1.不论是何种JOIN方式,test_Customers表和test_Orders表 首先生成笛卡尔积4*7=28条数据

     如图(显示笛卡尔积结果可使用CROSS JOIN关键字):

北京联动北方科技有限公司北京联动北方科技有限公司

STEP 2.使用ON的条件筛选笛卡尔积结果,我们可以看到SQL1的筛选条件更为严格。

     SQL1在STEP 2后保留的条目为 9、

     SQL2在STEP 2后保留的条目为 8、9、17、18、19、27

STEP 3.保留表test_Customers不符合ON条件的数据条目回加,回加后的的结果:

北京联动北方科技有限公司

最后.SQL2还有一个WHERE筛选,所以最终结果为

北京联动北方科技有限公司

我们发现JOIN ON AND和JOIN ON WHERE中的AND和WHERE根本就是不同处理阶段的筛选

只是因为内联接没有STEP 3,使两种筛选的结果一样

在外联接中就能深刻体会到SQL1和SQL2是两种不同业务逻辑的SQL语句了。

SQL1的业务逻辑:取出所有客户信息,如果客户有订单且订单号为2,则显示这个订单

SQL2的业务逻辑:取出订单号为2的客户信息和订单信息




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论