联合查询
联合查询:将多次查询(多条select语句),在记录上进行拼接(字段不会增加)。
基本语法:
多条selet语句构成:每一条selet语句获取的字段数必须严格- -致(但 是字段类型无关)。
Select语句1
Union [union选项]
Select语句2…
Union选项:与select选项-样有两个:
All:保留所有(不管重复)
Distinct.去重(整个重复):默认的
联合查询时数据类型可以不要求一样。
但是字段多少必须一致。
意义
- 查询同一张表,但需求不同。如:查询学生信息,文具价格升序,服装价格降序。
- 多表查询:多张表的结构是完全一样的保存的数据(结构)也是一-样的。(有利于提高查询效率)
order by的使用:第一次之所以会失败是因为在联合查询中,order by不能直接使用,需要用括号括起来。
但是很快就能发现,服装的确是按照降序排列,但是文具并没有像我们所预期的那样升序排列。这就牵扯到第二个知识点:limit。
若要order by生效,必须搭配limit(limit没有硬性规定,使用最大值即可)。
连接查询
连接查询:将多张表(可以大于2张)进行记录的连接(按照某个指定的条件进行数据拼接)。
最终结果是:记录数有可能变化,字段数一定会增加(至少两张表的合并)。
连接查询的意义:在用户查看数据的时候需要显示的数据来自多张表。
连接查询: join,使用方式:左表 join 右表
左表:在join关键字左边的表
右表:在ioin关键字右边的表
连接查询分类
SQL中将连接查询分成四类:内连接, 外连接,自然连接和交叉连接。
交叉连接
交叉连接: cross join,从一张表中循环取出每一条记录, 每条记录都去另外一张表进 行匹配:匹配一定保留(没有条件匹配),而连接本身字段就会增加(保留),最终形成的结果叫做:笛卡尔积。
基本语法:左表 cross join 右表;==== from 左表,右表;
笛卡儿积没有意义:应该尽量避免(交叉连接没有作用)。
交叉连接存在的价值:保证连接这种结构的完整性。
内连接
内连接: [inner] join,从左表中取出每一条记录,去右表中与所有的记录进行匹配:匹配必须是某个条件在左表中与右表中相同最终才会保留结果,否则不保留。
基本语法:左表 [inner] join 右表 on 左表.字段 = 右表.字段;on表示连接条件:条件字段就是代表相同的业务含义(如sh_goods.id和sh_goods_comment.goods_id)
注意:如果两张表字段不同(即两份表没有相同的id字段,则可以省略简写),如果有重复,则报错。
字段别名以及表别名的使用:在查询数据的时候,不同表有同名字段,这个时候需要加上表名才能区分,而表名太长,通常可以使用别名。
(内连接要求两边的表数据都存在,如果数据不存在,就无法进行连接)
内连接可以没有连接条件:没有 on之后的内容,系统会保留所有结果(即形成笛卡儿积)
内连接还可以使用where代替on关键字(不建议使用,where没有on效率高):
外连接
外连接: outer join,以某张表为主,取出里面的所有记录,然后每条与另外一张表进行连接:不管能不能匹配上条件,最终都会保留:能匹配,正确保留;不能匹配,其他表的字段都置空NULL。
外连接分为两种:是以某张表为主:有主表
Left join:左外连接(左连接)。以左表为主表
Right join:右外连接(右连接),以右表为主表
基本语法:左表 left/right join 右表 on 左表.字段=右表.字段;
左连接
报错,外连接与内连接不同,不能用where,只能用on。
右连接
虽然左连接和右连接有主表差异,但是显示的结果:左表的数据在左边,右表数据在右边。
左连接和右连接可以互转。
子查询
子查询可以理解为,在一个SQL语句A(SELECT.INSERT、UPDATE等)中嵌人- -个查询语句B,作为执行的条件或查询的数据源(代替FROM后的数据表),那么B就是子查询语句,它是一条完整的SELECT语句,能够独立地执行。(一条select语句内部包含另外一条select语句)。
子查询分类
子查询有两种分类方式:按位置分类,按结果分类。
按位置分类:子查询(select语句)在外部查询(select语句)中出现的位置。
- from子查询:子查询跟在from之后。
- where子查询:子查询出现在where之中。
- exists子查询:子查询出现exists里面。
按结果分类:根据子查询得到的数据进行分类(理论上讲任何一个查询得到的结果都可以理解为二维表)。
- 标量子查询:子查询得到的结果是一行一列。
- 列子查询:子查询得到的结果是一列多行。
- 行子查询:子查询得到的结果是多列一行(多列多行)。
上面几个出现的位置都是在where之后 - 表子查询:子查询得到的结果是多列多行(出现在from之后)。
数据源
数据源:数据的来源,关系型数据库的来源都是数据表:本质上只要保证数据类似二维表,最终都可以作为数据源.
数据源分为多种:单表数据源,多表数据源,查询语句
单表数据源: select * from 表名;
多表数据源:select * from 表名1,表名2;
从一张表中取出一条记录,去另外一张表中匹配所有记录而且全部保留:(记录数和字段数),将这种结果成为:笛卡尔积(交叉连接)。笛卡尔积没什么用,应该尽量避免。
子查询:数据的来源是一条查询语句(查询语句的结果是二维表)。
Select* from (select语句)as表名;
标量子查询
需求:已知商品名称为办公电脑,想获取该商品全部评论。
1.确定数据源:获取所有的评论;
select * from sh_goods_comment where goods_id=?;
2.获取商品ID:可以通过商品名称确定;
select * from sh_goods where name=‘办公电脑’;
标量子查询的实现
列子查询
需求:查询所有商品的属性值(商品属性表中存在的属性)
1.确定数据源:属性值;
select * from sh_goods_attr_value where attr_id in(?);
2.确定有效的属性值的id:所有属性id;
select id from sh_goods_attr;
列子查询的实现
列子查询返回的结果会比较: 一列多行,需要使用in作为条件匹配:其实在mysql中还有几个类似的条件: all, some, any。
·=any ==== in(其中一个即可);!=any(不等于其中一个即可)
·any ==== some(any和some是一样的);!=any ==== !=some
·=all (为全部);!=all(不等于全部的条件)
肯定结果
否定条件
行子查询
行子查询:返回的结果可以是多行多列(一行多列)
行子查询需要构造行元素:即由多个字段构成。
表子查询
表子查询:子查询返回的结果是多行多列的二维表:子查询返回的结果是当做二维表来使用。
表子查询:from子查询:得到的结果作为from的数据源。
子查询关键字
exists:Exists:是否存在的意思,exists子查询就是用来判断某些条件是否满足(跨表), exists是接在where之后(exists返回的结果只有0和1)