09 数据库查询(3) | OushuDB 数据库使用入门

本文详细介绍了数据库查询的高级技巧,包括内连接、外连接(左连接、右连接、全连接)、交叉连接以及如何结合查询条件进行数据筛选。通过实例展示了各种连接方式的使用,如内连接的`JOIN`与`USING`的区别,以及外连接在处理不匹配数据时的特性。此外,还讲解了组合查询中的`UNION ALL`和`UNION`,用于合并多个查询结果集,满足复杂查询需求。

表连接、组合查询

大家好,本节课程我们将学习数据查询的进阶部分,主要包括表连接和组合查询。

在上一节的课程中,我们尝试了在两个数据表中通过不同的条件来查询想要的数据,但是在很多情况下,我们也需要连接不同的表来完成数据的查询。

多表连接

  • inner join

  • out join

  • left join

  • right join

  • full join

  • cross join

常见的表连接方式包括内连接、外连接、交叉连接等方式。

内连接

在查询的时候,比较不同表中要连接的列的值的连接称为内连接,不匹配的行不会显示在结果中。

内连接的SQL关键字JOIN 或者INNER JOIN,两种语法等价,通常可以直接写成JOIN,同时使用using或on指定连接属性/条件。

它的表达式为:

T1 [INNER] JOIN T2 ON boolean_expression

T1 [INNER] JOIN T2 USING ( join column list )

我们以两个简单的表单来演示内连接的效果,tableA中数据的id分别为1、2、3,tableB中数据的id分别为1、2、4。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

两个表单如果有相同的字段名id,我们可以通过join using()来进行内连接:

select * from tableA inner join tableB using(id);

编辑切换为居中

添加图片注释,不超过 140 字(可选)

我们可以发现,两个表单中通过id列,对id列数值相同的数据1、2这两行进行了连接。

另外,我们也可以通过join on来对两个表单的任意字段进行匹配,即使两个字段名称不同,例如:

select * from tableA inner join tableB on tableA.id=tableB.id;

通过对比,我们可以看到两种内连接的方式显示结果稍有区别,通过using(id)来完成表单的内连接,会将两个表单的id列并为一列,而on的方式是将两个表中的两个字段的值进行比较。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

on的方式跟我们之前学过的 select * from tableA,tableB where tableA.id=tableB.id;的结果是一致的,我们一般称第一种为显式内连接操作,第二种为隐式内连接操作。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

回到上一课的举例中,我们可以在员工信息表和部门信息表中通过两个表单中的部门编号字段 d_id 和 e_deptid来完成等值比较,来获取两张表单中其他对应的字段。例如,当我们需要查询员工信息以及其部门所在位置时,可以通过下面的查询语句来完成:

select e_name,e_position,d_name,d_city from employee join department on d_id=e_deptid;

select e_name,e_position,d_name,d_city from employee,department where d_id=e_deptid;

编辑切换为居中

添加图片注释,不超过 140 字(可选)

外连接

外连接包括左连接、右连接和全连接三种类型。

左连接

前面我们提到,在内连接的查询进行匹配的时候,只保留部分的行数数据,对不匹配的数据不保留。

那么如果,我们在连接员工信息表的时候,只希望查询和获取其他表单的内容,即使部分员工未查询到必要的信息,也对该员工在信息表中的原始内容进行保留时,我们可以通过左外连接 left (outer) join来完成,无法匹配的字段用null来补充,

它的表达式为:

T1 LEFT [OUTER] JOIN T2 ON boolean_expression

T1 LEFT [OUTER] JOIN T2 USING ( join column list )

那么根据我们的 查询需求,我们可以使用以下查询语句:

select * from tableA left join tableB on tableA.id=tableB.id;

编辑切换为居中

添加图片注释,不超过 140 字(可选)

这样,我们可以在tableA的基础上,来查询和匹配tableB的数据。

在员工信息表和部门信息表中,我们可以通过

select e_name,e_position,d_name,d_city from employee left join department on d_id=e_deptid;

来查询。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

这样,我们查询到的语句,就包括了完整的20条员工信息。

右连接

同理,右连接提供了一个对应的相反结果,我们可以以右边表为主表,保留右表全部内容,并且在对左边表单进行匹配过程中,不能匹配的数据不再保留。

T1 RIGHT [OUTER] JOIN T2 ON boolean_expression

T1 RIGHT [OUTER] JOIN T2 USING ( join column list )

例如,我们通过tableA右连接tableB,

select * from tableA right join tableB on tableA.id=tableB.id;

编辑切换为居中

添加图片注释,不超过 140 字(可选)

可以发现结果中未显示tableA的id为3的行,保留了tableB的id为4的行。

全连接

除了左连接、右连接,我们还有一种全连接full join的方法,可以完成对两张表单的连接,并同时保留两侧无法匹配上的数据,无法匹配的字段用null来补充。

T1 FULL [OUTER] JOIN T2 ON boolean_expression

T1 FULL [OUTER] JOIN T2 USING ( join column list )

select * from tableA full join tableB on tableA.id=tableB.id;

编辑切换为居中

添加图片注释,不超过 140 字(可选)

这样,tableA和tableB中所有的id不匹配的行均得到保留。

左连接、右连接、全连接,三种外连接的查询结果对比如下:

编辑切换为居中

添加图片注释,不超过 140 字(可选)

交叉连接

交叉连接,是一种不带WHERE 子句的连接方式。

表达式为 T1 CROSS JOIN T2

它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

比如,tableA中有3行数据,tableB中也有3行数据,则交叉连接检索到的记录数将等于3*3=9行。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

最后,还有一种 NATURAL JOIN的表达方式,它是USING的缩写形式,通过NATURAL JOIN可以自动形成一个由两个表中同名的列组成的USING列表。

T1 NATURAL { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2

编辑切换为居中

添加图片注释,不超过 140 字(可选)

例如,tableA NATURAL JOIN tableB 的效果和tableA inner join tableB using(id) 相同。

但如果没有同名的列,NATURAL JOIN的查询结果等同于CROSS JOIN,这部分内容就不再赘述啦,大家可以在课后去尝试一下。

连接查询搭配查询条件

以上介绍了多种表连接方式,它们可以很灵活的与上节课介绍的多种查询条件一起来完成数据查询,例如,我们需要基于员工表去查询对应的部门信息,同时要求部门名称模糊匹配为“开发xx”部:

select e_name,e_position,d_name,d_city from employee left join department on d_id=e_deptid WHERE d_name like '开发%'

编辑切换为居中

添加图片注释,不超过 140 字(可选)

更多的查询语句,大家可以根据自己的具体需求去设计和尝试。

组合查询

  • UNION ALL 直接对查询结果进行合并

  • UNION 对查询结果合并并去重

除了对查询表单进行组合,我们有时候也需要对查询结果进行组合,通过UNION ALL / UNION 我们可以直接对两个查询语句的结果进行合并,例如:

我们需要查询我们需要查询所有开发部的员工,以及所有在北京的员工,我们可以通过

select e_name,e_position,d_name,d_city from employee left join department on d_id=e_deptid WHERE d_name LIKE '开发%' UNION ALL select e_name,e_position,d_name,d_city from employee left join department on d_id=e_deptid WHERE d_city= '北京'

来完成,当然,这个查询需求也可以通过一个语句来完成,但是考虑到更加复杂的在不同表单中、多重过滤条件的查询,通过union all 来进行查询结果合并的优势更加明显。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

检视查询结果我们可以发现合并结果中有重复数据,此时,我们可以通过 union 来替换union all,则结果会自动去重。

编辑切换为居中

添加图片注释,不超过 140 字(可选)

考虑在大规模查询时的工作效率,union 需要更多的时间来完成查询,大家可以根据自己的需求来选择需要的组合查询方式。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值