十三、联合(union) 查询
13.1、联合查询概念
含义:
联合查询是指将2个或2个以上的字段数量相同的查询结果,“纵向堆叠” 后合并为一个结果。
图示如下: |
select id, f1, f2 from join1
union
select id2, c1, c2 from join2;
13.2、联合查询语法
语法形式:
select查询1
union [all 或distinct]
select查询2
union [all 或distinct]
select查询3
..............
[order by字段 [ asc 或desc] ]
[limit 起始行号, 数量] ;
说明:
① 所有单个查询结果应该具有相等的列数。
② 所有单个查询的列类型应该具有一致性(即每个查询的第n列的数据类型一致)。
③ 单个查询的列名可以不同,但最终的列名是第一个查询的列名(可以使用别名)。
④ union 可以带all或distinct参数,如果省略就是distinct,即默认已经消除重复行了。
⑤ 最后的order by或limit是对整个联合之后的结果数据进行排序或数量限定。
⑥ order bv子句中的排序字段应该使用第一个查询中的字段名,如果有别名就必须使用别名。
⑦ 可见,假设:
查询1有n1行,m列;
查询2有n2行,m列;
则两个表“联合”之后的结果,有最多n1+n2行,m列。
十四、连接(join)查询
连接(join)查询是将两个查询的结果以“横向对接”的方式合并起来的结果。
对比:联合查询是将两个查询的结果以“纵向堆叠”的方式合并起来的结果。
14.1、连接查询概述
连接查询,是将两个查询(或表)的每一行,以“两两横向对接”的方式,所得到的所有行的结果。
即一个表中的某行,跟另一个表中的某行,进行“横向对接”,而得到一个新行。
如下图所示:
对接之后,就是:
可见,假设:
表1有n1行,ml列;
表2有n2行,m2列;
则表1和表2“连接”之后,就会有:
n1 * n2行;
m1 + m2列。
连接查询基本形式如下:
select from 表1 [连接方式] join 表2 [ on 连接条件] where … ;
可见,连接查询只是作为from子句的“数据源”。
或者说,连接查询是扩大了数据源,从原来的一个表作为数据源,扩大为多个表作为数据源。
连接查询包括以下这些不同形式;
交叉连接,内连接,外连接(分:左外连接,右外连接)。
14.2、交叉连接(cross join)
语法形式:
from 表1 [cross] join 表2
说明:
① 交叉连接其实可以认为是连接查询的“完全版本”,即所有行都无条件地都连接起来了;
② 关键字“cross"可以省暗;
③ 交叉连接又称为“笛卡尔积”, 通常应用价值不大;
④ 交叉连接还有一种写法: from 表1, 表2;
14.3、内连接 ( inner join )!!!
语法形式:
from表1 [ inner ] join 表2 on连接条件
说明:
① 内连接其实是交叉连接的基础上,再通过on条件而筛选出来的部分数据。
② 关键字“inner"可以省略,但建议写上。
③ 内连接是应用最广泛的一种连接查询,其本质是根据条件筛选出“有意义的数据”。
④ on 是内连接的关键。
14.4、外连接
外连接分为左外连接和右外连接。
14.4.1、左外连接(left join) :
语法形式:
from表1 left [outer] join 表2 on连接条件
说明:
① 左外连接其实是保证左边表的数据都能够取出的一种连接。
② 左外连接其实是在内连接的基础上,再加上左边表中所有不能满足条件的数据。
③ 关键字“outer”可以省略。
14.4.2、右外连接(right join) :
语法形式:
from 表1 right [outer] join表2 on连接条件。
说明:
① 右外连接其实是保证右边表的数据都能够取出的一种连接。
② 右外连接其实是在内连接的基础上,再加上右边表中所有不能满足条件的数据。
③ 关键字“outer”可以省略。
扩展:
左连接,右连接,其实是可以互换的一一无非是把两个表的顺序调换一下。
14.5、自连接
自连接不是一种新的连接形式,而只是一个表“自己跟自己连接”,这怎么做到呢?
语法形式:
from 表1 as a [连接形式] join 表1 as b on a.xxx字段1 = b.xxx字段名
说明:
① 自连接其实还是两个表连接,只是将一个表用不同的别名,当做两个表。
② 自连接适用于一个表中的某个字段的值“来源于”当前表的另一个字段的情况。
示例:
要求查询每个城市及其所在省份,结果类似如下所示:
城市 省份
石家庄 河北省
保定 河北省
需求:找出所有城市及其省份
十五、子查询(subquery )
15.1、子查询的概念
子查询就是指一个“正常查询语句”中的某个部分(比如select部分,from 部分,where 部分)又出现了
查询的一种查询形式,比如:
select * from xxx表名where price >= (一个子查询语句);
此时,子查询所在上“上层查询”,就被称为主查询。
也可以这么说 : 子查询是为主查询的某个部分提供某种数据的查询。
上一条语句中,括号中的子查询语句如果查出的是一个“某个数值”( 比如3000 ),则其就相当于:
select * from XXX表名 where price >= 3000;
15.2、标量子查询
● 含义:
标量子查询就是指子查询的结果是“单个值”(一行一列)的查询。
● 使用:
标量子查询通常用在where子句中,作为主查询的一个条件判断的数据。
本质上,标量子查询的结果,就可以直接当做“一个值”来使用。
15.3、列子查询(in 中应用)
● 含义:
列子查询查出的结果为**“一列数据”**,类似这样:
select pinpai from product where chandi=“北京”;
结果为:
● 使用:
列子查询通常用在where子句的in运算符中,代替in运算符中的“字面值”列表数据。
比如:
select * from product wpere chandi in ( ‘北京’,’深圳’,’天津’);
如果in中的数据并不方便一个一个列出,但可以通过一个查询得到,就可以使用查询来实现:
select * from product where chandi in ( select chandi from product price > 4000 ):
15.4、行子查询
● 含义:
行子查询查出的结果通常是一行,类似这样:
select pinpai, chandi from product where price=11499;
结果为:
● 使用:
行子查询的结果通常跟“行构造符”一起,在where条件子句中做为条件数据,类似这样:
where (字段1, 字段2) = (行子查询)
或
where row(字段1,字段2) = (行子查询) //含义跟上一行是一样的,即row可以省略
示例:
15.5、表子查询
● 含义:
当一个子查询查出的结果是**“多行多列”**的时候,就是表子查询。
表子查询的结果相当于一个表,可以直接当做一个表来使用。
● 使用:
表子查询通常用在主查询的from子句中,作为一个“数据源”。
注意:
此时需要给该子查询设置一个别名, 类似这样:
from (select… 子查询) as tab1 .
结果都是
15.6、有关子查询的特定关键字
15.6.1、in关键字
in关键字在子查询中主要用在列子查询中代替人为手工罗列出来的多个“字面值”数据。
举例:
找出联想品牌的商品都有哪些类别。
15.6.2、any关键字
any关键字用在比较操作操符的后面,表示查询结果的多个数据中的任一个满足该比较操作符就算满足。(类似于 or )
举例:
找出在北京生产的但价格比在深圳生产的任一商品贵的商品。
15.6.3、all关键字
all关键字用在比较操作操符的后面,表示查询结果的多个数据中的所有都满足该比较操作符才算满足。
举例:
找出在北京生产的但价格比在深圳生产的所有商品都贵的商品。
15.7、exists(存在)子查询
● 形式:
where exists( 任何子查询)
● 含义:
该子查询如果”有数据”,则该exists()的结果为”true”,即相当于where true(恒真)
该子查询如果”无数据”,则该exists()的结果为”false",即相当于where false (恒假)
● 说明:
① 此子查询语句通常需要用到主查询语句中的字段作为查询条件。
● 特别注意:
通常,有意义exists子查询不能单独执行
对比: 之前的4种子查询都可以单独执行