SQL 三种基本Join
Join是关系型数据库系统的重要操作之一,SQL常用Join:内联接、外联接和交叉联接等。
这里讨论一下这常用的三种连接。
测试环境:db2 v10.1, linux
表定义:
1 --用户 2 CREATE TABLE USER 3 ( 4 USERID INTEGER NOT NULL, 5 COMPANYID INTEGER, 6 TELNO VARCHAR(12) 7 ); 8 9 --公司 10 CREATE TABLE COMPANY 11 ( 12 COMPANYID INTEGER NOT NULL, 13 TELNO VARCHAR(12) 14 );
数据:
--USER USERID COMPANYID TELNO ----------- ----------- ------------ 11 2 777777 22 3 123456 33 4 567890 --COMPANY COMPANYID TELNO ----------- ------------ 2 888888
1. inner join
[db2inst1@win ~]$ db2 "select * from user inner join company on user.companyid=company.companyid" USERID COMPANYID TELNO COMPANYID TELNO ----------- ----------- ------------ ----------- ------------ 11 2 777777 2 888888 1 record(s) selected.
注意:内联接(Inner join)满足交换律:“A inner join B” 和 “B inner join A” 是相等的。
查看访问计划:
Optimized Statement: ------------------- SELECT Q2.USERID AS "USERID", Q2.COMPANYID AS "COMPANYID", Q2.TELNO AS "TELNO", Q1.COMPANYID AS "COMPANYID", Q1.TELNO AS "TELNO" FROM DB2INST1.COMPANY AS Q1, DB2INST1.USER AS Q2 WHERE (Q2.COMPANYID = Q1.COMPANYID) Access Plan: ----------- Total Cost: 13.5566 Query Degree: 1 Rows RETURN ( 1) Cost I/O | 1 HSJOIN ( 2) 13.5566 2 /-----+------\ 3 1 TBSCAN TBSCAN ( 3) ( 4) 6.77858 6.77776 1 1 | | 3 1 TABLE: DB2INST1 TABLE: DB2INST1 USER COMPANY Q2 Q1
用HSJOIN的方式进行,DB2对此进行了重写。
2. outer join
外部联接保存一个或两个输入表的所有行,即使无法找到匹配联接谓词的行。
[db2inst1@win ~]$ db2 "select * from user left outer join company on user.companyid=company.companyid" USERID COMPANYID TELNO COMPANYID TELNO ----------- ----------- ------------ ----------- ------------ 11 2 777777 2 888888 33 4 567890 - - 22 3 123456 - - 3 record(s) selected.
[db2inst1@win ~]$ db2 "select * from user right outer join company on user.companyid=company.companyid" USERID COMPANYID TELNO COMPANYID TELNO ----------- ----------- ------------ ----------- ------------ 11 2 777777 2 888888 1 record(s) selected.
查看访问计划:
Optimized Statement: ------------------- SELECT Q2.USERID AS "USERID", Q2.COMPANYID AS "COMPANYID", Q2.TELNO AS "TELNO", Q1.COMPANYID AS "COMPANYID", Q1.TELNO AS "TELNO" FROM DB2INST1.COMPANY AS Q1 LEFT OUTER JOIN DB2INST1.USER AS Q2 ON (Q2.COMPANYID = Q1.COMPANYID) Access Plan: ----------- Total Cost: 13.5566 Query Degree: 1 Rows RETURN ( 1) Cost I/O | 1 HSJOIN< ( 2) 13.5566 2 /-----+------\ 3 1 TBSCAN TBSCAN ( 3) ( 4) 6.77858 6.77776 1 1 | | 3 1 TABLE: DB2INST1 TABLE: DB2INST1 USER COMPANY Q2 Q1
这里也是用的HSJOIN。
3. cross join
交叉联接(cross join)执行两个表的笛卡尔积(就是把表A和表B的数据进行一个N*M的组合)。也就是说,它匹配一个表与另一个表中的每一行;我们不能通过使用ON子句在交叉联接指定谓词,虽然我们可以使用WHERE子句来实现相同的结果,这是交叉联接基本上是作为一个内部联接了。
[db2inst1@win ~]$ db2 "select * from user cross join company" USERID COMPANYID TELNO COMPANYID TELNO ----------- ----------- ------------ ----------- ------------ 11 2 777777 2 888888 22 3 123456 2 888888 33 4 567890 2 888888 3 record(s) selected.
查看访问计划:
Optimized Statement: ------------------- SELECT Q2.USERID AS "USERID", Q2.COMPANYID AS "COMPANYID", Q2.TELNO AS "TELNO", Q1.COMPANYID AS "COMPANYID", Q1.TELNO AS "TELNO" FROM DB2INST1.COMPANY AS Q1, DB2INST1.USER AS Q2 Access Plan: ----------- Total Cost: 13.5563 Query Degree: 1 Rows RETURN ( 1) Cost I/O | 3 NLJOIN ( 2) 13.5563 2 /-----+------\ 1 3 TBSCAN TBSCAN ( 3) ( 4) 6.77776 6.77858 1 1 | | 1 3 TABLE: DB2INST1 TABLE: DB2INST1 COMPANY USER Q1 Q2
看到这里使用的是NLJOIN。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端