一、DQL介绍
1. DQL是什么
DQL(Data Query Language) :数据查询语言
所有的查询操作都用:Select,不仅使用频率最高,也是最核心的
2. 标准语法
SELECTselect_list
[ INTOnew_table ]
FROMtable_source
[ WHEREsearch_condition ]
[ GROUPBY group_by_expression ]
[ HAVINGsearch_condition ]
[ ORDERBY order_expression [ ASC | DESC ] ]
3. DQL,DDL,DML,DCL,TCL介绍及关系
DDL,DML,DCL,DQL,TCL共同组成数据库的完整语言。
二、指定查询字段
MySQL,可以在 SELECT 语句的字段列表中指定,要查询的字段。
这里介绍的都是一些常用的,肯定是不全面的,可以自己依葫芦画瓢,试一试其他的
1. 查看指定表的所有字段信息
show full columns from 表名字;
2. 查询指定字段
1. 作用:
查询指定字段的数据
2. 格式
SELECT 字段名 FROM 表名;
SELECT 字段名1,字段名2,…… FROM 表名;
注意:会先查询字段1的数据在查询字段2的数据
3. 实例
在 student 查询 name 字段和 gender 字段的数据
SELECT name FROM student
3. 别名(AS)
1. 作用
利用 AS 可以给字段起别名,也可以给表起别名
2. 格式
SELECT 字段名 AS 新名字 FROM 表名字 AS 新名字
SELECT 字段名1 AS 新名字 字段名2 AS 新名字 FROM 表名字 AS 新名字
3. 实例
查询 student 表中的 name 和 gender 字段的信息,并设 name 字段别名为学生姓名字段,gender 字段别名学生成绩字段,student 表别名 S 表:
SELECT `name` AS 学生姓名,`gender `AS 学生成绩 FROM student AS S
4. 连接函数
1. concat(str1,str2,...)
没有分隔符地连接字符串
2. concat_ws(separator,str1,str2,...)
含有分隔符地连接字符串
3. group_concat(str1,str2,...)
连接一个组的所有字符串,并以逗号分隔每一条数据(当成一个组即可)
4. 去重 DISTINCT
在表中,可能会包含重复值。这并不成问题,不过,有时希望仅仅列出不同DISTINCT的值。
关键词 distinct用于返回唯一不同的值。
distinct必须放在开头
1. 作用:
去除select语句查询出来的结果中重复的语句,重复的语句只显示一条
2. 实例:
除去 A 表中 id 和 name 重复的数据然后显示
select distinct name,id from A
3. 和 count 结合使用
select count(distinct name) from A;
5. 数据库的列(表达式)
SELECT VERSION() --查询系统版本(函数)
SELECT 100*3-1 AS 计算结果 -- 用来计算(表达式)
SELECT @@auto_increment_increment --查询自增的步长(变量)
6. 计算
学员考试成绩 +1 分,建立别名 并查看
SELECT `StudentNo`,`StudentResult`+1 AS '提分后' FROM result
三、where 条件子句
1. 作用:
使用where子句对表中的数据筛选,并将筛选结果输出。
2. 语法
select 字段列表 from 表名 where语句 ;
3. 按逻辑运算符筛选
1. 介绍:
2. 实例:
查询考试成绩在95分到100分之间
SELECT `StduentNo`,`StudentResult` FROM result
WHERE StudentResult >=95 AND StudentResult<=100
SELECT `StduentNo`,`StudentResult` FROM result
WHERE NOT StudentNo = 1000
4. 按关系运算符筛选
5. 范围查询
1. 介绍:
1. in
2. between 大数值 and 小数值
2. 实例:
in
查询1001 1002 1003 学员信息
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1001
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1002
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo = 1003
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentNo IN (1001,1002,1003);
查询在北京的学生
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `Address` IN('安徽','河南洛阳');
查询age等于10或者11的数据:
select * from student where age in (10,11)
与上面语句等效:
select * from student where age=10 or age=11
between
查询学生成绩在95到100的数据
SELECT `StduentNo`,`StudentResult` FROM result
WHERE StudentResult BETWEEN 95 AND 100
查询age在10到24之间的数据,包含边界值:
select * from student where age between 10 and 24
6. 空判断
is null
is not null
查询地址为空的学生
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE address=''OR address IS NULL
查询有出生日期的同学 不为空
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE `BornDate` IS NOT NULL;
查询address为null的数据:
select * from student where address is null
查询address不为null的数据:
select * from student where address is not null
5、模糊查询
1. 介绍:
like
%表示任意多个字符(包括0)
_表示任意一个字符
escape:取消%或_字符的通配符特性
2. 实例:
查询姓刘的同学
like结合 %(代表0到任意字符) _(一个字符)
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentName LIKE '刘%';
查询姓刘的同学,名字后只有一个字
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentName LIKE '刘_';
查询姓刘的同学,名字后只有两个字
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentName LIKE '刘__';
查询名字中间有嘉字的同学 %嘉%
SELECT `StudentNo`,`StudentName` FROM `student`
WHERE StudentName LIKE '%嘉%';
查询name中姓张的数据:
select * from student where name like '王%'
查询name中两个字姓张的数据:
select * from student where name like '张_
查询name中含有"%"的数据
select * from student where name like '%A%%' escape 'A'
四、连接查询
连接查询的意义: 在用户查看数据的时候,需要显示的数据来自多张表.
1. 内连接查询
内连接查询是最常见的连接查询,内连接查询可以查询两张或两张以上的表
1. 内连接:[inner] join:
从左表中取出每一条记录,去右表中与所有的记录进行匹配: 匹配必须是某个条件在左表中与右表中相同最终才会保留结果,否则不保留.
基本语法:左表 [inner] join 右表 on 左表.字段 = 右表.字段;
on表示连接条件: 条件字段就是代表相同的业务含义(如my_student.c_id和my_class.id)
当两个表中存在相同意义的字段的时候,就可以通过该字段来连接查询这两个表,当该字段的值相同时就可以查出该记录。
内连接可以没有连接条件: 没有on之后的内容,这个时候系统会保留所有结果。
2. 实例:
select a.id,a.name,a.sex,b.country,b.city,b.street
from student a
join addr b
on a.addrid=b.addrid;
2. 外连接查询
以某张表为主,取出里面的所有记录, 然后每条与另外一张表进行连接: 不管能不能匹配上条件,最终都会保留: 能匹配,正确保留; 不能匹配,其他表的字段都置空NULL。
1. 左连接:
left join: 左外连接(左连接), 以左表为主表
基本语法: from 左表 left join 右表 on 左表.字段 = 右表.字段;
左表不管能不能匹配上条件,最终都会保留:能匹配,正确的保留;若不能匹配,右表的字段都置NULL。
2. 左连接实例:
select a.id,a.name,a.addrid,b.country,b.city
from student a left join addr b
on a.addrid=b.addrid;
3. 右连接:
right join: 右外连接(右连接), 以右表为主表
基本语法: from 左表 right join 右表 on 左表.字段 = 右表.字段;
右表不管能不能匹配上条件,最终都会保留:能匹配,正确的保留; 若不能匹配,左表的字段都置NULL。
4. 右连接实例:
select a.id,a.name,a.addrid,b.country,b.city
from student a right join addr b
on a.addrid=b.addrid;
五、联合查询
1. 概述:
联合查询结果是将多个select语句的查询结果合并到一块因为在某种情况下需要将几个select语句查询的结果合并起来显示。比如现在需要查询两个公司的所有员工的信息,这就需要从甲公司查询所有员工信息,再从乙公司查询所有的员工信息,然后将两次的查询结果进行合并。
可以使用union和union all关键字进行操作
2. 格式:
select 语句1
union[union 选项]
select 语句2
union|[union 选项]
select 语句n
其中union选项有两个选项可选
all:表示无论重复都输出
distinct: 去重(整个重复)(默认的)
3. 实例:
select *from addr
union all
select *from addr;
select id,addrid
from addr
union all
select id,addrid
from student;
联合查询只要求字段一样, 跟数据类型和顺序无关
4. 联合查询的意义:
查询同一张表,但是需求不同 如查询学生信息, 男生身高升序, 女生身高降序
多表查询: 多张表的结构是完全一样的,保存的数据(结构)也是一样的.
5. 联合查询order by的使用
在联合查询中: order by不能直接使用(不能出现两次),需要对查询语句使用括号才行;
select *from student
where sex="woman"
order by score
union
select *from
student where sex="man"
order by score;
这种情况是会报错的。因为语句中不允许出现两个order by。
select *from student where sex="woman"
union
select *from student where sex="man" order by score;
如果是上边这样只出现一次他的意义就是等合并完成之后再进行排序就没有任何意义了,因为又把前边sex分好的类打乱了
(select *from student
where sex="woman"
order by score )
union
(select *from
student where sex="man"
order by score;)
这种方式的目的是为了让两个结果集先分别order by,然后再对两个结果集进行union。但是你会发现这种方式虽然不报错了,但是两个order by并没有产生最后的效果,所以应该改成如下:
select *from
(select *from student
where sex="woman"
order by score)student
union
select *from
(select *from student
where sex="man"
order by score)student ;
也就是说,order by不能直接出现在union的子句中,但是可以出现在子句的子句中。
六、子查询
通常我们在查询的SQL中嵌套查询,称为子查询。子查询通常会使复杂的查询变得简单,但是相关的子查询要对基础表的每一条数据都进行子查询的动作,所以当表单中数据过大时,一定要慎重选择
本质:在where语句中嵌套一个子查询语句
1. 带in关键字的子查询
使用in关键字可以将原表中特定列的值与子查询返回的结果集中的值进行比较
如果某行的特定列的值存在,则在select语句的查询结果中就包含这一行。
例:查询成绩大于80的学生的所有信息,
先在子查询中查出成绩大于80的结果集,然后将原成绩表中的成绩与结果集进行比较,如果存在,就输出这条学生的记录。
select *
from student
where score in
(select score from student where score>80);
2. 带比较运算符的子查询
如果可以确认子查询返回的结果只包含一个单值,那么可以直接使用比较运算符连接子查询。
经常使用的比较运算符包括等于(=)、不等于(<>或!=)、小于(<)、大于(>)、小于等于(<=)和大于等于(>=)。
select *
from student
where score>
(select score
from scholarship
where dengji=1);
查询奖学金等级为1的学生信息
3. 查询奖学金等级为1的学生信息
exists: 是否存在的意思, exists子查询就是用来判断某些条件是否满足(跨表),
exists是接在where之后
exists返回的结果只有0和1.
例:如果存在成绩大于90的人则列出整个表的记录
select *
from student
where exists
(select *from student where score>90);
4. 带any关键字的子查询
any关键字表示满足其中的任意一个条件,使用any关键字时,只要满足内层查询语句结果的的任意一个,就可以通过该条件来执行外层查询语句。
select *
from student
where addrid<any
(select addrid
from addr);
5. 带all关键字的子查询
all和any刚好是相反的,all关键字表示满足所有结果,使用all关键字,要满足内层查询语句的所有结果,才可以通过该条件来执行外层查询语句。
select *
from student
where addrid>all
(select addrid
from addr);
6. 查询 数据库结构-1的所有考试结构(学号,科目编号,成绩) 降序
方式一: 连接查询
SELECT `StudentNo`,r.`SubjectName`,`StudentResult` FROM `result` r INNER JOIN `subject` sub ON r.SubjectNo = sun.SubjectNo WHERE subjectName = '数据库结构-1' ORDER BY StudentResult DESC
方式二:使用子查询(由里及外)
SELECT `StudentNo`,r.`SubjectName`,`StudentResult` FROM `result` WHERE StudentNo=( SELECT SubjectNo FROM `subject` WHERE SubjectName = '数据库结构-1' ) ORDER BY StudentResult DESC
分数不少于80分的学生的学号和姓名
SELECT DISTINCT s.`StudentNo`,`StudentName` FROM student s INNER JOIN result r ON r.StudentNo = s.StudentNo WHERE StudentResult>=80
在这个基础上 增加一个科目 ,高等数学-2
SELECT DISTINCT s.`StudentNo`,`StudentName` FROM student s INNER JOIN result r ON r.StudentNo = s.StudentNo WHERE StudentResult>=80 AND `SubjectNo`=( SELECT Subject FROM `subject` WHERE SubjectName='高等数学-2' )
查询课程为 高等数学-2 且分数不小于80分的同学的学号和姓名
SELECT s.`StudentNo`,`StudentName` FROM student s INNER JOIN result r ON s.StudentNo = r.StudentNo INNER JOIN `subject` sub ON r.`SubjectName`='高等数学-2' WHERE `SubjectaName`='高等数学-2' AND StudentResult >=80
再改造 (由里即外)
SELECT `StudentNo`,`StudentName` FROM student WHERE StudentNo IN( SELECT StudentNo result WHERE StudentResult >80 AND SubjectNo =( SELECT SubjectNo FROM `subject` WHERE `SubjectaName`='高等数学-2' ) )
七、分页和排序
1. 排序:
升序ASC 降序 DESC
语法:
SELECT xx
FROM xx
JOIN xx
WHERE xx
ORDER BY xx
ASC或者DESC
2. 分页
1. 为什么要分页
缓解数据库压力,给人的体验更好
2. 注意点
分页,每页显示五条数据
3. 语法:
语法:limit(查询起始下标,pagesize)
limit 0,5 1-5
limit 1,5 1-5
limit 6,5
第一页 limit 0,5
第二页 limit 5,5
第三页 limit 10,5
第N页 limit 5*(n-1),5
4. 实例:
SELECT s.`StudentNo`,`StudentName`,`SubjectName`,`StudentResult` FROM student s INNER JOIN `result` r ON s.`StudentNo`=r.`StudentNo` INNER JOIN `subject` sub ON r.`subjectNo`=sub.`subjectNo` WHERE subjectName='数据结构-1' ORDER BY StudentResult ASC LIMIT 0,5
八、分组
-- 查询不同课程的平均分,最高分,最低分,平均分大于80
-- 核心:(根据不同的课程分组)
SELECT `SubjectName`,AVG(StudentResult),MAX(StudentResult) FROM result r INNER JOIN `Subject` sub ON r.SubjectNo=sub.SubjectNo
GROUP BY r.SubjectNo -- 通过什么字段来分组 HAVING AVG(StudentResult)>80