目录
DQL:(Data Query Language 数据查询语言)用于查询数据库对象中所包含的数据
DQL语言的语句为:SELECT
DQL语言是数据库语言中最核心、最重要的语句,也是使用频率最高的语句
查询的主要类型有:单表查询,多表复杂查询和子查询
select语法
先建个表并添加数据
- drop table if exists user;
- create table if not exists user(
- id int(4) comment'id',
- name varchar(10) comment '姓名',
- stuage int(3) comment '年龄',
- birth date comment '出生日期',
- phone varchar(11) comment '电话',
- address varchar(50) comment '地址',
- gender varchar(1) comment '性别',
- sutdentnumber varchar(8) comment '学号'
- );
- insert into user (id, name, stuage, birth, phone, address, gender, sutdentnumber) values
- (001,'张三',18,'1999-2-4',1353435,'河南','男','10023'),
- (002,'李四',19,'1999-2-4',1384112,'山东','男','10025'),
- (003,'王五',20,'1999-2-4',186411223,'河南','男','10028'),
- (004,'李国华',21,'1999-2-4',135994112,'安徽','男','10343'),
- (005,'川建国',22,'1999-2-4',1864112678,'河北','男','10223');
- select 字段1,字段2,字段3,.....from 表名;
-
- //查询全部信息,不建议书用
- select * from 表名;
实例;
- //查询所有信息
- select id, name, stuage, birth, phone, address, gender, sutdentnumber from user ;
-
- select * from user;
可给数据列取一个新别名
可给表取一个新别名
可把经计算或总结的结果用另外一个新名称来代替
- select 字段1[AS 别名],字段2[AS 别名]....from 表名;
- AS 可省略
例如:
select name AS '姓名', stuage as '年龄', birth '出生日期', phone '电话', address '地址', gender '性别', sutdentnumber'学号' from user ;
select DISTINCT 字段列表FROM 表名;
例如:
- //查询学生地址,去除重复的
- select distinct address'年龄' from user;
在查询中使用常量列:如果需要将一些常量的默认信息添加到输出结果中,以方便统计或计算。可以使用常量列。
例如:
select name AS '姓名', stuage as '年龄', birth '出生日期', phone '电话', '白描小区',address '地址' from user;
搜索条件可有一个或多个逻辑表达式组成,结果一般为真或假
搜索条件的组成:逻辑操作符和比较操作符
| 操作符名称 | 语法 | 描述 |
| AND或&& | a AND b 或 a && b | 逻辑与,同时为真,结果才为真 |
| OR或|| | a OR b 或 a||b | 逻辑或,只要一个为真,则结果为真 |
| NOT或! | NOT a 或 !a | 逻辑非,若操作数位假,结果则为真 |
| 操作符名称 | 语法 | 描述 |
| is null | a is null | 若操作符为NULL,则结果为真 |
| IS NOT NULL | a IS NOT NULL | 若操作符不为NULL,则结果为真 |
| BETWEEN | a BETWEEN b AND c | 若a范围在b与c之间则结果为真 |
| LIKE | a LIKE b | SQL模式匹配,若a匹配b,则结果为真 |
| IN | a IN (a1,a2,a3,….) | 若a等于a1,a2…中的某一个,则结果为真 |
注意:
1.数值数据类型的记录之间才能进行算术运算
2.相同数据类型的数据之间才能进行比较
NULL空值条件查询
NULL代表无值;区别于值0和空字符串;只能出现在定义允许为NULL的字段;
需使用IS NULL 或 IS NOT NULL 比较操作符去比较
语法:
SELECT 字段1,字段2 ,…FROM 表名 WHERE 字段x IS NULL
BETWEEN AND范围查询:根据一个范围值来检索
SELECT 字段1,字段2 ,…FROM 表名 WHERE 字段x BETWEEN 值1 AND 值2
例如:
select id, name, stuage, birth, phone, address, gender, sutdentnumber from user where fraction between 70 and 80;
LIKE 模糊查询
在where子句中,使用LIKE关键字进行模糊查询,它与%一起使用,表示匹配0或任意多个字符,与_一起使用,表示匹配单个字符。
例如:
- //查询名字带张的
- select id, name, stuage, birth, phone, address, gender, sutdentnumber from user where name like '李%';
- //查询名字带张且为两个字的
- select id, name, stuage, birth, phone, address, gender, sutdentnumber from user where name like '张_';
使用 IN 进行范围查询
在where子句中,使用 IN 关键字进行范围查询,查询的字段x的值,至少与括号中的一个值相同,多个值之间用英文逗号隔开
语法:
SELECT 字段1,字段2 ,…FROM 表名 WHERE 字段x IN ( 值1,值2,值3…值n)
例如:
select id, name, stuage, birth, phone, address, gender, sutdentnumber from user where stuage in (19,20,21);
| 函数名 | 作用 |
| AVG() | 返回某字段的平均值 |
| COUNT() | 返回某字段的行数 |
| MAX() | 返回某字段的最大值 |
| MIN() | 返回某字段的最小值 |
| SUM() | 返回某字段的和 |
注意:聚合函数除了COUNT(),一般用于数值类型。
AVG语法:
- //求学生的平均分
- select avg(fraction)from user;
COUNT()语法:
- //返回字段的总行数,
- select count(1) from user;
- //如果name字段有空值则不会将其统计
- select count(name) from user;
注意:
count()括号里如果为数字则会把所有带信息的行数显示出来,如果使用字段名查看,如果查看的字段有空值则不会统计所在的行数。例如一个表共有10行数据,如果name字段有两个空值count(name)返回的信息为8,空值不计算
MAX()语法
- //找出最大值
- select max(fraction) from user;
MIN()语法
- //找出最小值
- select min(fraction) from user;
SUM()语法
- //求和
- select sum(fraction) from user;
| 函数名 | 作用 | 举例 |
| CEIL(X) | 返回大于或等于数值x的最小整数 | SELECT CEIL(2.3) 返回:3 |
| FLOOR(X) | 返回小于或等于数值x的最大整数 | SELECT FLOOR(2.3) 返回:2 |
| RAND() | 返回0~1间的随机数 | SELECT RAND() 返回:0.5525468583708134 |
实例:
- //返回数字3
- select ceil(2.3);
- //返回数字2
- select floor(2.3);
- //返回一个0到1的随机数
- select rand();
| 函数名 | 作用 | 举例(结果与当前时间有关) |
| CURDATE() | 获取当前日期 | SELECT CURDATE(); 返回:2016-08-08 |
| CURTIME() | 获取当前时间 | SELECT CURTIME(); 返回:19:19:26 |
| NOW() | 获取当前日期和时间 | SELECT NOW(); 返回:2016-08-08 19:19:26 |
| WEEK(date) | 返回日期date为一年中的第几周 | SELECT WEEK(NOW()); 返回:26 |
| YEAR(date) | 返回日期date的年份 | SELECT YEAR(NOW()); 返回:2016 |
| HOUR(time) | 返回时间time的小时值 | SELECT HOUR(NOW()); 返回:9 |
| MINUTE(time) | 返回时间time的分钟值 | SELECT MINUTE(NOW()); 返回:43 |
| DATEDIFF(date1,date2) | 返回日期参数date1和date2之间相隔的天数 | SELECT DATEDIFF(NOW(), '2008-8-8’); 返回:2881 |
| ADDDATE(date,n) | 计算日期参数date加上n天后的日期 | SELECT ADDDATE(NOW(),5); 返回:2016-09-02 09:37:07 |
- -- 获取当前日期
- select curdate();
- -- 获取当前时间
- select curtime();
- -- 获取当前日期和时间
- select now();
- -- 返回日期data为一年中的第几周
- select week(now());
- -- 返回日期date的年份
- select year(now());
- -- 返回时间time的小时值
- select hour(now());
- -- 返回时间time的分钟值
- select minute(now());
- -- 返回日期参数date1和date2之间相隔的天数
- select datediff(now(),'2020-8-8');
- -- 计算日期参数date加上n天后的日期
- select adddate(now(),5);
ORDER BY子句:实现按一定顺序显示查询结果。
排序可以是升序(ASC)或者降序(DESC),如果不指定ASC或DESC,结果集默认按ASC升序排序。
语法:
- -- 按年龄升序
- select stuage from user order by stuage asc ;
- -- 按年龄降序
- select stuage from user order by stuage DESC ;
LIMIT 子句:MySQL查询语句中使用LIMIT子句限制结果集
语法:
- #第一条记录的偏移量为0
- -- 分页查询 LIMIT 0,3 第一个数表示起始位置,第二个数表示查询的个数,从0位置开始查询,0,1,2
- select id, name, stuage, birth, phone, address, gender, sutdentnumber,fraction from user LIMIT 0,3;
- -- 分页查询 LIMIT 3,3 第一个数表示起始位置,第二个数表示查询的个数,从3位置开始查询,3,4,5
- select id, name, stuage, birth, phone, address, gender, sutdentnumber,fraction from user LIMIT 3,3;
- -- 分页查询 LIMIT 6,3 第一个数表示起始位置,第二个数表示查询的个数,从6位置开始查询6,7,8
- select id, name, stuage, birth, phone, address, gender, sutdentnumber,fraction from user LIMIT 6,3;
语法:GROUP BY
GROUP BY作用:使用GROUP BY关键字对查询结果分组
对所有的数据进行分组统计
分组的依据字段可以有多个,并依次分组
与HAVING结合使用,进行分组后的数据筛选
GROUP BY子句经常和聚合函数结合使用完成分组统计功能
实例:
- -- 按性别查询人数
- -- 分组按性别查询人数
- select count(1) count, gender from user group by gender ;
- -- 分组组查询成绩大于80的男生人数
- select count(1) count ,fraction, gender from user group by fraction,gender having fraction > 80 and gender = '男';
- -- 分组查询地址为河南的人数
- select count(1) count ,address from user group by address having address = '河南';
- -- 分组查询地址为河北的男女人数
- select count(1) count, address, gender from user group by address,gender having address = '河北';
- -- 分组查询地址和分数大于80的女生人数
- select count(1) count, address, gender, fraction from user group by address, gender, fraction having fraction > 80 and gender = '女';
- -- 分组查询出生在1999-1-1年到2000-1-1年的人数
- select count(1) count, birth from user group by birth having birth between '1999-1-1' and '2000-1-1';
WHERE与HAVING的区别
WHERE子句:用来筛选 FROM 子句中指定的操作所产生的行
GROUP BY子句:用来分组 WHERE 子句的输出
HAVING子句:用来从分组的结果中筛选行
编写顺序
- SELECT
- 字段列表
- FROM
- 列表名
- WWHERE
- 条件列表
- GROUP BY
- 分组字段列表
- HAVING
- 分组后条件列表
- ORDER BY
- 排序字段列表
- LIMT
- 分页参数
执行顺序
- FROM----------1
- 列表名
- WWHERE--------2
- 条件列表
- GROUP BY------3
- 分组字段列表
- HAVING--------4
- 分组后条件列表
- SELECT--------5
- 字段列表
- ORDER BY------6
- 排序字段列表
- LIMT----------7
- 分页参数
子查询有:标量子查询,行子查询,列子查询,表子查询
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询。子查询在WHERE语句中的一般用法
语法:
SELECT … FROM 表名 WHERE 字段X 比较运算符(子查询)
注意:
1、习惯上,外层查询称为父查询,圆括号中嵌入的查询称为子查询 2、执行SQL语句时,先执行子查询,返回所有来自子查询的结果,再执行外围的父查询,返回查询的最终结果(即求解方式为由里及外)。
3、将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个(否则会出现提示信息:错误代号1242 Subquery returns more than 1 row)。
IN后面的子查询可以返回多条记录。
常用IN替换等于(=)的子查询
语法:
SELECT … FROM 表名 WHERE 字段X IN(子查询)
EXISTS 子查询:带有EXISTS的子查询不返回任何记录的数据,只返回逻辑值“True”或“False”。
语法:
SELECT …… FROM 表名 WHERE EXISTS(子查询);
注意:
1、子查询有返回结果: EXISTS子查询结果为TRUE,执行外层查询;
2、子查询无返回结果: EXISTS子查询结果为FALSE, 外层查询不执行;
子查询注意事项
任何允许使用表达式的地方都可以使用子查询
嵌套在父查询SELECT语句的子查询可包括:SELECT子句;FROM子句;WHERE子句;GROUP BY子句;HAVING子句
只出现在子查询中而没有出现在父查询中的列不能包含在输出列中
子查询的结果是单个值(数字,字符串,日期),最简单的形式,这种子查询成为标量子查询
常用的操作符:= 、<> 、> 、>=、 <、 <=
例如:
select classno from studentmage where name = '李白';
运行结果:

通过查找班级号来查找他所在的班级
- -- 通过查找李白的班级号来查找他所在的班级
- select name from class where classno = (select classno from studentmage where name = '李白');

子查询返回的结果是一行(可以是多行),这种子查询成为行子查询。
常用的操作符有:=、<>、IN、NOT IN
select salary,managerid from emp where name = '张无忌';
将结果作为条件进行子查询
select * from emp where (salary,managerid) = (select salary,managerid from emp where name = '张无忌');
查询结果显示多行
子查询返回结果是一列(可以说多列),这种查询称为列子查询
常用的操作符:IN、NOT IN、ANY、SOME、ALL

例如
select id from where name = '销售部' or name ='市场部';
将结果作为条件进行子查询
select * from emp where id in (select id from where name = '销售部' or name ='市场部');
子查询返回的结果是多行多列,这种子查询成为 表子查询
联合查询关键字:union、union all
对于union查询,就是把多次查村的结果合并起来,形成一个新的查询结果集
语法
- select 字段列表 from 表A、表B...
- union[all]
- select 字段列表 from 表A、表B...
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
union all 会将查到的全部数据结合在一起(可能有重复的),union 合并后会去重。
多表连接查询是通过各个表之间共同列的关联性(例如:外键)来查询的。
1、内连接(INNER JOIN) ,可简写为 JOIN;
2、左外连接(LEFT OUTER JOIN),可简写为LEFT JOIN;
3、右外连接(RIGHT OUTER JOIN),可简写为RIGHT JOIN;
4、自连接查询;
5、交叉连接(CROSS JOIN)也称为 笛卡儿乘积连接,基本上用不到。
内连接:内连接使用比较运算符根据每个表的通用列中的值匹配两个表中的行。
语法:
- #第一种写法
- SELECT 字段列表 FROM 表1 INNER JOIN 表2
- ON 表1.通用字段名=表2.通用字段名
-
- #第二种写法
- SELECT 字段列表 FROM 表1 ,表2
- WHERE 表1.通用字段名=表2.通用字段名
注意:
如果两个表中有相同的字段名,必须在列名前加表名。否则将出现 错误代码:1052 Column 'studentno' in field list is ambiguous
实例:
- #第一种写法
- SELECT s.studentno,s.studentname,r.studentresult FROM
- student AS s INNER JOIN result AS r
- ON s.studentno=r.studentno ORDER BY r.studentresult DESC
- #第二种写法
- SELECT s.studentno,s.studentname,r.studentresult FROM
- student AS s,result AS r
- WHERE s.studentno=r.studentno
- ORDER BY r.studentresult DESC
语法
- #左外连接
- SELECT 字段列表 FROM 表1 LEFT JOIN 表2
- ON 表1.通用字段名=表2.通用字段名
左外连接:左表(表1)的记录将会全部表示出来,而右表(表2)只会显示符合匹配条件的记录。
1.匹配,返回到结果集
2.无匹配,NULL值返回到结果集
实例:
- SELECT s.studentno,s.studentname,r.studentresult FROM
- student AS s
- LEFT JOIN
- result AS r
- ON s.studentno=r.studentno
- ORDER BY r.studentresult DESC
- #右外连接
- SELECT 字段列表 FROM 表1 RIGHT JOIN 表2
- ON 表1.通用字段名=表2.通用字段名
右外连接:右表(表2)的记录将会全部表示出来,而左表(表1)只会显示符合匹配条件的记录。
1.匹配,返回到结果集
2.无匹配,NULL值返回到结果集
| 操作符名称 | 描述 |
| INNER JOIN | 如果表中有至少一个匹配,则返回行 |
| LEFT JOIN | 不论右表是否有匹配,都会返回左表的所有行 |
| RIGHT JOIN | 不论左表是否有匹配,都会返回右表的所有行 |