软件测试学习 之连接查询和联合查询

9 篇文章 0 订阅
1 篇文章 0 订阅

连接查询

分为 交叉连接,内连接和外连接

一、交叉连接(cross join)

 有两种,显式的和隐式的,不带on子句,返回的是两表的乘积,也叫笛卡尔积。

 以下两个查询结果是相同的

-- 隐式交叉连接
select o.id, o.order_number, c.id, c.name
from orders o , customers c
-- 显式交叉连接
select o.id,o.order_number,c.id,c.name
from orders o cross join customers c

 

二、等值连接

 在连接条件中使用等于号(=)运算符,其查询结果中列出被连接表中的所有列,包括其中的重复列。

select  * from T_student s,T_class c 

where s.classId = c.classId

 

三、自然连接(natural join)


  自然连接是一种特殊的等值连接,他要求两个关系表中进行比较的必须是相同的属性列,无须添加连接条件,并且在结果中消除重复的属性列。经MySQL验证,自然连接下不允许使用on语句


select name, course_id
from courses natural join teaches

注:

1. 连接多张表时,注意不同含义不要同名,否则会查询不到结果

-- score表存在与student表同名的sid,以及与course表同名的cid
-- course表中存在与student相同的字段name导致查询到记录为空
select * FROM score
NATURAL JOIN student
NATURAL JOIN course

-- 修改couse表name字段为cname,返回结果正常
select * FROM student s
NATURAL JOIN score sc 
NATURAL JOIN course_copy cc

2. 两张表>6个字段相同时,会查询不到结果

-- student_copy表保留了6个字段
select * FROM student_copy
NATURAL JOIN student

 

四、内连接(inner join)

有两种,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行。

(所谓的链接表就是数据库在做查询形成的中间表)。

join子句中没有使用outer / inner等前缀,默认连接类型是inner join

隐式的内连接,没有inner join,一般称为等值连接,形成的中间表为两个表的笛卡尔积。

生成笛卡尔积的临时表,之后再用where后的条件进行筛选,内存占用较大

--隐式内连接,又称等值连接
select o.id,o.order_number,c.id,c.name
from customers c, orders o
where c.id=o.customer_id;

 显示的内连接,一般称为内连接,有inner join,形成的中间表为两个表经过on条件过滤后的笛卡尔积

在连接其他表时,会先用on条件判断,再生成记录,查询效率优于等值连接

-- 显式内连接,简称内连接
select o.id,o.order_number,c.id,c.name
from customers c inner join orders o 
on c.id=o.customer_id;

五、外连接(outer join)

外连接分三类:左外连接(left outer join)、右外连接(right outer join)和全外连接(full outer join),

outer 关键字是省略的,通常简称为左连接(left  join)、右连接(right join)和全连接(full join)

三者的共同点:

都返回符合连接条件和查询条件(即:内连接)的数据行。

不同点:
左外连接还返回左表中不符合连接条件单符合查询条件的数据行(即左表独有的数据,右表内容用null表示,只记录一条)
右外连接还返回右表中...(参照上面描述)。
全外连接还返回左表&右表中...(参照上面描述)。

左外连接(left outer join)

-- 左外连接(left outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c 
on c.id=o.customer_id;

右外连接(right outer join) 

-- 右外连接(right outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o right outer join customers c on c.id=o.customer_id;

 全外连接(full outer join)

-- 全外连接(full outer join)
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o full outer join customers c 
on c.id=o.customer_id;

注意:mysql是不支持全外的连接的(mysql中没有full outer join关键字),这里给出的写法适合oracle和db2。但是可以通过左外和右外联合查询来获取全外连接的查询结果。

-- 使用union关键字连接左外连接和右外连接
select e.empName,d.deptName
     FROM t_employee e 
     left JOIN t_dept d
     ON e.dept = d.id
UNION
select e.empName,d.deptName
     FROM t_employee e 
     RIGHT JOIN t_dept d
     ON e.dept = d.id;

补充说明:

1。on后面的条件(on条件)和where条件的区别:

on条件:是过滤两个链接表笛卡尔积形成中间表的约束条件。
where条件:在有on条件的select语句中过滤中间表的约束条件。在没有on的单表查询中,是限制物理表或者中间查询结果返回记录的约束(此时中间表为交叉连接形成的笛卡尔积)。在两表或多表连接中是限制连接形成最终中间表的返回结果的约束。
从这里可以看出,将where条件移入on后面是不恰当的。

推荐的做法是:
on只进行连接操作,where只过滤中间表的记录,即 写连接查询的时候,on后面只跟连接条件,而对中间表限制的条件都写到where子句中。

where条件放在on后面查询的结果是不一样的。例如:

-- where条件独立书写
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c 
on c.id=o.customer_id
where o.order_number<>'mike_order001';
-- 不单独使用where条件,而把条件加入on后面
select o.id,o.order_number,o.customer_id,c.id,c.name
from orders o left outer join customers c 
on c.id=o.customer_id and o.order_number<>'mike_order001';

从查询的结果来看,显然是不相同的,下面一条语句显示的结果是难以理解的。

 

2. 如果两张表的关联字段名相同时,可以使用USING子句,相当于where和on条件中的 "=”

-- 交叉连接,使用using
select * FROM score sc
cross JOIN course c
using(cid)

-- 使用on作为条件
select * FROM score sc
cross JOIN course c
on sc.cid=c.cid

-- 使用where条件
select * FROM score sc
cross JOIN course c
where sc.cid=c.cid

 

联合查询(union)

联合查询:就是把多个查询语句的查询结果结合在一起

主要语法1:... UNION ... 
主要语法2:... UNION ALL ...

UNION 与 UNION ALL的区别:联合查询支持UNION 与 UNION ALL两种用法,其中UNION 会把多个查询语句的结果合并后去重UNION ALL会把所有的查询结果合并,包括重复的数据。

说明: 
查询要求的列数一致(可以来自于多张表或者视图),列名可能不一致,以第一次的列名为准
推荐: 查询的每一列相对应的列类型一样
如果不同的语句中取出的行完全一致,则会合并成一行

-- 联合查询
select s1.`name` from student s1
UNION (select s2.`name` from student s2) 

 以上查询结果等同于单独查询一张表

 

 

以上所有内容参考以下文章整理

作者:留兰香丶 
原文:https://blog.csdn.net/codejas/article/details/80227404 
作者:超级阿尼玛 
原文:https://blog.csdn.net/communicate_/article/details/8675759 
作者:一天进步一点点lgh 
原文:https://blog.csdn.net/lu0422/article/details/78892497 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值