数据查询操作中使用频率最高的SQL语句是select语句。
简单查询
简单查询主要是基于一张表的数据筛选和数据统计。
1.1 查询指定的字段
常错点:字段之间用“,”(英文输入法下逗号)隔开
语法格式: select 字段列表 from 表名;
例:select * from student; " * " 代表所有的字段。
select 学号,姓名 from 学生信息;
查询学生信息表student的学号、姓名、年龄;
select 学号,姓名,year(now()-year(出生日期)) as 年龄 from student;
as 关键字对查询结果中的列表重名,即为别名(as也可以省略)
select 图书名称,单价*0.75 折后价 from book;
字段列表允许使用运算符
1.2 条件查询
语法格式:select 字段列表 from 表名 where 条件表达式;
select * from course where 学分>1;
1.3 多条件查询
一、带and的多条件查询
语法格式: select 字段列表 from 表名 where 条件表达式1 and 条件表达式2 [....and 条件表达式n];
select * from student where 性别='女' and 班级编号=3;
Between .... and 关键字:当条件表示的是一个取值范围时,可用between ... and 代替,该子句用于判断某个字段值是否在指定的范围内。
语法格式:select 字段列表 from 表名 where 字段名 [not] between 值1 and 值2;
not:可选参数,加上not 表示不在指定的范围内;
值1:表示范围的起始值;值2表示范围的终止值。
select * from student where 班级编号 between 2 and 4;
二、带or的多条件查询
or(或) 关键字只要满足查询条件中的任何一个,那么记录就会被加入查询结果集中
语法格式:select 字段列表 from 表名 where 条件表达式1 or 条件表达式2 [.....or 条件表达式n];
select * from student where 班级编号='1' or 班级编号='3';
in 关键字:可以判断字段的值是否在集合中,如果在该记录被加入到查询结果集中,否则该记录不被查询。
select 字段列表 from 表名 where 字段名 [not] in(值1,值2,....);
not是可选参数,加上not表示不在集合内满足条件。
select * from student where 班级编号 in (1,4,5,2);
1.4 模糊查询(like)
%——可以匹配一个或多个字符,可以代表任意长度的字符串,长度为0。
" _ "——下划线只匹配一个字符
语法格式:select 字段列表 from 表名 where 字段名 [not] like 模式;
select * from student where 姓名 like '%依';
select * from student where 姓名 like '_依';
1.5 空值查询(is null)
is null 可以用来判断条件是否为空值null (如果字段是空值,则满足查询条件,如果字段不是控制,则相反)
语法格式:表达式 is [not] null;
select * from choose where 成绩 is null;
1.6 查询结果排序(order by)
排序的方向是升序(asc)(从第一行从小到大)或降序(desc)(从第一行依次减小)
默认为升序。
语法格式:order by 字段名1 [asc | desc] , [.....,字段名2 [asc | desc]];
select 学号,课程号,成绩 from choose
where 课程号='2'
order by 成绩 desc, 学号;
1.7 limit 子句
查询表中的前几条或者中间某几条记录,可以使用谓词关键字 limit 实习。
语法格式:select 字段列表 from 数据源 limit [start,] length;
start 表示从第几行开始检索,length 表示检索记录的行数。数据表中第一行记录的start值为0。
当查询结果集从第一行开始输出,start可以省略。
select 学号,课程号,成绩 from choose
where 课程号='2'
order by 成绩 desc, 学号
limit 3;
1.8 去除重复行(distinct)
使用 distinct 关键字可以去除查询结果的重复记录
语法格式:select distinct 字段名 from 表名;
select distinct 学号 from choose;
聚合函数与group by子句
聚合函数用于对一组值进行计算并返回一个汇总值(group by子句需要和聚合函数一起使用)
1.1 count() 函数
count()函数中的参数可以用 “ * ”代替,如 count( * ),统计时包含了null值的行。
count(*)是经过内部优化的,能够很快返回表中所有的记录总数。
select count(学号) 总人数 from student;
select count(*) 总人数 from student;
1.2 max()函数和min()函数(求最大值和最小值)
select max(成绩), min(成绩) from choose where 课程号='1';
1.3 sum()函数和avg()函数(求总和和平均值)
select sum(下单数量),avg(下单数量) from dingdan;
1.4 分组查询 group by子句
通过group by 子句可以将数据划分到不同的组中,再统计每一组内的数据,实现对记录的分组查询。
在查询时,所查询的字段必须包含在分组的字段中,目的是使查询到的数据没有矛盾。
select 班级编号,count(*) 班级总人数 from student group by 班级编号;
1.5 having子句
having子句用于设置分组或聚合函数的过滤筛选条件,having子句通常与group by子句一起使用。
语法格式:select 字段列表 from 表名 group by 字段名 having 条件表达式;
select 学号,count(课程号) from choose
group by 学号 having count(课程号) < 3;
多表连接查询
表与表之间的数据关联性通过设置外键实现。
表连接的语法格式:select 字段列表 from 表名1 [连接类型] join 表名2 on 表1和表2之间的连接条件。
1.1 全连接(交叉连接)
表与表之间的连接没有任何条件筛选,连接后的结果集包含连接表的全部数据,结果集中的字段数是连接表字段数总和,记录数是连接表记录数的乘积。
select student.*,classes.* from classes join student;
from 子句产生的一个中间结果,表中的每条记录都是与其他表中记录交叉产生的所有可能的组合,也就是笛卡儿积。
1.2 内连接 (inner join)
如果按照某种条件筛选连接表时,结果集中都是满足要求的记录,这种表连接的方式是内连接。
语法格式: select 字段列表 from 表名1 [inner] join 表名2 on 表1和 表2之间的连接条件;
其中inner关键字可以省略,只需指定on的条件。
select 学号,姓名,student.班级编号,班级名称
from student join classes
on student.班级编号 = classes.班级编号;
注意:两张数据表连接时如果存在相同的字段名,在使用改字段时需要指出具体的表名,即:表名.字段名 。例如:student.班级编号
1.3 外连接(outer join)
外连接又分为左连接(left join)、右连接(right join)、完全连接(full join)
与内连接不同,外连接(左和右连接)的连接条件只筛选一张表的数据,对另一张表不进行筛选(该表的所有记录都出现在结果集中)
1)左连接(left join)
语法格式:select 字段列表 from 表1 left join 表2 on 表1和表2之间的连接条件。
注:包含表1的的全部记录,只筛选表2,若表2中没有满足连接条件的记录,则结果集中表2相应的字段填入null。
select student.学号,姓名,count(课程号) 选课门数
from student left join choose
on student.学号 = choose.学号
group by student.学号;
2)右连接(right join)
语法格式:select 字段列表 from 表1 right join 表2 on 表1和表2之间的连接条件。
注:包含表2的的全部记录,只筛选表1,若表1中没有满足连接条件的记录,则结果集中表1相应的字段填入null。
3)表的自身连接(两张表连接时如果表名相同称为表的自身连接)
语法格式:select 字段列表 from 表1 a join 表1 b on a和b的连接条件;
a和b是表1的重命名,连接时相当于表1被使用两次。
select a.学号,a.姓名,a.出生日期,b.学号,b.姓名,b.出生日期
from student a join student b
on a.出生日期 < b.出生日期
where b.姓名='孙悟空';
嵌套查询
将一个查询语句块嵌入在另一个查询语句块的条件子句中的查询称为嵌套查询,又称为子查询。包含有子查询的select语句称为主查询。
通常子查询必须写在小括号 () 里。子查询可以包含查询语句中的所有子句,嵌套在主查询select语句中的where子句和having子句中。
1.1 比较运算符子查询
如果子查询结果返回的是一个单值,则可以使用比较运算符和主查询连接
语法格式:select 字段列表 from 表1 where 表1中的字段值 >=(任何比较运算符都可)
(select 表2 中的字段 from 表2 where 条件表达式);
select sum(下单数量) from dingdan
where 买家id =(select 买家id from buyer where 姓名='无情');
1.2 in运算符子查询
当子查询的结果是多个值时(一个列表),与子查询连接时只能用in运算符。
语法格式:select 字段列表 from 表1 where 表1中的字段 [not] in (select 表2中的字段 from 表2
where 条件表达式);
select * from course
where 课程号 in(select 课程号 from choose where 学号='1906010849');
一个查询语句可以嵌套多个子查询。
select * from course
where 课程号 in(select 课程号 from choose where 学号=(
select 学号 from student where 姓名='孙悟空'));
1.3 exists 运算符子查询(查询是否有记录)
exists 逻辑运算符用于检测子查询的结果集是否包含有记录,如果结果集中至少包含有一条记录,则exists的结果为true 否则为false;exists加上not时,与上述结果恰恰相反。
exists——有记录
not exists——没有记录
语法格式:select * from 表1 where not exists (select * from 表2 where 条件表达式 );
查询没有被任何学生选修的课程信息。
select * from course
where not exists(select * from choose where choose.课程号=course.课程号);
1.4 any、all运算符子查询
运算符 | 语义 | 运算符 | 语义 | |
>any | 大于子查询的某一个值 | >all | 大于子查询的所有值 | |
>=any | 大于等于子查询的某个值 | >=all | 大于等于子查询的所有值 | |
<any | 小于子查询的某一个值 | <all | 小于子查询的所有值 | |
<=any | 小于等于子查询的某个值 | <=all | 小于等于子查询的所有值 | |
=any | 等于子查询结果中的某个值 | =all | 等于子查询结果中所有值 | |
!=any | 不等于子查询结果中的某个值 | !=all | 不等于子查询结果中所有值 |
语法格式(以>=all为例):select 字段列表 from 表1 where 表1中的字段或表达式
>=all(select 表2中字段 from 表2 [where 条件表达式]);
例:查询最贵的书
select * from book
where 单价 >=all(select 单价 from book);