多表查询
多表连接的应用场景
结果集中的记录保持在多张表中。
按范式要求设计表结构
-- 第二范式: 每个非主属性必须完全依赖于主属性
-- 第三范式: 每个非主属性不能依赖于另一个非主属性
多表连接的种类
根据结果集生成的规则不同,连接可以分为:
交叉连接(cross join)
内连接 (inner join)
外连接 (outer join)
交叉连接
假设table1表中有m条记录,table2表中有n条记录,交叉连接产生的结果集为m*n
该连接产生的结果集称为笛卡尔积。
select tabname1.colname1,tabname2.colname2 from tabname1 cross join tabname2;
交叉连接
select a.real_name,a.id,s.account_id,s.unix_host,s.os_username from account a cross
join service s;
问题:
哪些记录有意义 ?
select a.real_name,a.id,s.account_id,s_unix_host,s.os_username from
account a cross join service s where a.id=s.account.id;
内连接:
语法
如果有多个条件表达式,on关键字后面跟一个,其余用AND条件连接。
select tabname1.colname1,tabname2.colname2 from tabname1 join tabname2
on tabname1.colname1 = tabname2.colname2 and tabname1.colname2 = val1;
项目案例:
列出申请了远程登录业务的客户姓名以及在unix服务器上的开通信息。
内连接原理 (一)
t1表和t2表做内连接,连接条件为on t1.c1 = t2.c2,假设t1表做驱动表,t2表做匹配表,记录的匹配过程如下:
1.从t1表中读取第一条记录r1,若它的c1值为1 .
2.根据该值到t2表中查找匹配的记录,即需要遍历t2表,从t2表中的第一条记录开始,若该记录(r1)的c2列的值等于1,我们就说这两条记录能够匹配上,那么t1的r1和t2的r1组合起来,作为结果集里的一条记录,否则检查t2表中的下一条记录。
3.安装方法2依次将t2表中所有的记录检查一遍,只要匹配就放入结果集中
4.从t1表中读取第二条记录,依次重复步骤2和3,产生最终的结果集。
内连接原理 (二)
t1表和t2表做内连接,连接条件为 on t1.c1 = t2.c2,假设t1表做驱动表,t2表做匹配表,记录的匹配有如下三种情况:
1.t1表中的某条记录在t2表中找不到任何一条匹配的记录,那么t1表中的该记录不会出现在结果集中
2.t1表中的某条记录在t2表中只有一条匹配的记录,那么t1表中的该记录和t2表中匹配的记录组合成新记录出现在结果集中。
3.t1表中的某条记录在t2表中有多条匹配的记录,那么t1表中的该记录会和t2表中的每一条匹配的记录组合成新记录出现在结果集中。
4.内连接的核心为任何一张表里的记录一定要在另一张表中找到匹配的记录,否则不能出现在结果集中。
内连接原理 (三)
t1表和t2表做内连接
连接条件为 on t1.c1 = t2.c2 ,两种方式都可以得到相同的结果集。
1. 一种t1表做驱动表 , t2表做匹配表
2. 另一种t2表做驱动表,t1表匹配表
3. 无论哪种方式最终得到的结果集都一样,所不同的是效率
内连接的结果集
内连接结果集的结构
t1.col1 t1.col2 t1.col3 ... ... t2.col1 t2.col2 t2.col3
内连接语言的执行顺序
先根据on和and条件对要连接的表进行过滤,将过滤后的结果集进行内连接操作(join,on),再根据select 语句的定义生成最终结果集 。
内连接中用ON和WHERE都可以
select tabname1.colname1,tabname2.colname2 from tabname1 join tabname2 on
tabname1.colname1 = tabname2.colname2 and tabname1.colname2 = val1;