文章目录
MySQL入门
执行如下代码
CREATE TABLE student3 (
id int,
name varchar(20),
age int,
sex varchar(5),
address varchar(100),
math int,
english int
);
INSERT INTO student3(id,NAME,age,sex,address,math,english) VALUES
(1,'马云',55,'男','杭州',66,78),
(2,'马化腾',45,'女','深圳',98,87),
(3,'马景涛',55,'男','香港',56,77),
(4,'柳岩',20,'女','湖南',76,65),
(5,'柳岩',20,'男','湖南',86,NULL),
(6,'刘德华',57,'男','香港',99,99),
(7,'马德',22,'女','香港',99,99),
(8,'德玛西亚',18,'男','南京',56,65);
排序查询
Order by 子句
如果我们需要对读取的数据进行排序,我们就可以使用 MySQL 的 ORDER BY 子句来设定你想按哪个字段哪种方式来进行排序,再返回搜索结果。
-
语法
order by 子句 order by 字段1 排序方式1,字段2 排序方式2,...
注意: 1.排序方式有2种:升序 asc 降序 desc ,默认升序 2.如 字段1 和 字段2 排序有冲突,字段1 优先满足。 3.如字段1数据相同,再按照字段2的排序方式排序。
我们来看几个例子
-- 默认情况按升序排列
select * from student3 order by age;
select * from student3 order by age asc;
-- 指定desc后按降序排列
select * from student3 order by age desc;
-- 注意:字符串也是可以排序的,排序依据为字符编码的二进制值
select name from student3 order by name;
GROUP BY 语句
GROUP BY 语句根据一个或多个列对结果集进行分组。
-- 查询address
select address from student3;
-- 使用distinct关键字
select distinct address from student3;
-- group by 分组查询
--这其实跟distinct返回的结果一致
select address from student3 group by address;
-- 当查询多个列的数据时
-- 查询name和address
select name,address from student3;
-- 用distinct试试
-- 这里只是去重了name
select distinct name,address from student3;
-- 用group by 试试
-- 结果集name,address一组都相同才会去重
select name,address from student3 group by name,address;
聚合函数
聚合函数aggregation function又称为组函数。 默认情况下 聚合函数会对当前所在表当做一个组进行统计,MySQL提供了许多聚合函数,包括AVG
,COUNT
,SUM
,MIN
,MAX
等。除COUNT
函数外,其它聚合函数在执行计算时会忽略NULL
值。
聚合函数的特点
1.每个组函数接收一个参数(字段名或者表达式),统计结果中默认忽略字段为NULL的记录
2.要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。
3.不允许出现嵌套 比如sum(max(xx))
AVG函数
AVG()函数计算一组值的平均值。 它计算过程中是忽略NULL
值的。
select * from student3;
-- 查询数学成绩的平均值
select avg(math) from student3;
select avg(math) 数学平均成绩 from student3;
-- 计算过程中是忽略NULL值的
select * from student3;
select avg(english) from student3;
COUNT()函数
COUNT()函数返回结果集中的行数。
select * from student3;
select count(*) from student3;
select count(1) from student3;
-- 创建的表每一行都有id,所以可以通过id来统计
select count(id) from student3;
-- 统计性别男和女各有多少人
select sex, count(*) from student3 group by sex;
注意:count() 在统计时,会计入null值。
MAX()函数
MAX()函数返回一组值中的最大值
-- 查询math最大值
select max(math) from student3;
MIN()函数
MIN()函数返回一组值中的最小值
-- 查询math最小值
select min(math) from student3;
现在我们设想一个应用场景,计算公司部门的员工最高工资和最低工资,先创建表。
drop table emp;
create table emp(
emp_id int primary key auto_increment,
emp_name varchar(20) comment '员工姓名',
emp_dept varchar(20) comment '部门名称',
salary decimal(10, 2) comment '工资',
hiredate datetime comment '入职时间'
);
insert into emp(emp_name, emp_dept, salary, hiredate) values('赵大', '开发部', 4500, '2016-3-1');
insert into emp(emp_name, emp_dept, salary, hiredate) values('陈二', '开发部', 5000, '2015-5-6');
insert into emp(emp_name, emp_dept, salary, hiredate) values('张三', '开发部', 7000, '2012-7-4');
insert into emp(emp_name, emp_dept, salary, hiredate) values('李四', '测试部', 5500, '2015-3-5');
insert into emp(emp_name, emp_dept, salary, hiredate) values('王五', '测试部', 3500, '20180407');
insert into emp(emp_name, emp_dept, salary, hiredate) values('钱六', '销售部', 6000, '20170909');
insert into emp(emp_name, emp_dept, salary, hiredate) values('周七', '财务部', 5200, '20170709');
select * from emp;
我们要如何统计各个部门的最高工资和最低工资呢?
-- 查询最高工资的部门
-- 不满足要求
select emp_dept, max(salary) from emp;
-- 先把部门分组,在查询
select emp_dept, max(salary) from emp group by emp_dept;
select emp_dept, min(salary) from emp group by emp_dept;
分组前条件 和 分组后条件 过滤结果集
- where 分组前条件
- having 分组后条件
注意:
1.where 在分组前进行条件过滤,不满足条件的记录不参与分组,不能跟 聚合函数
2.having 在分组后进行条件限定,不满足限定的记录不会被查询出来, 可以跟 聚合函数
统计各个部门的最低工资,要求入职时间在2015-01-01到2016-12-31之间
select emp_dept, max(salary) from emp where hiredate between '20150101' and '2016-12-31' group by emp_dept;
统计各个部门的最低工资,要求入职时间在2015-01-01到2016-12-31之间,并且最后查询结果只有一个部门
select emp_dept, max(salary) from emp where hiredate between '20150101' and '2016-12-31' group by emp_dept having count(emp_dept)=1;
SUM()函数
SUM()函数返回一组值的总和,SUM()函数忽略NULL
值。如果找不到匹配行,则SUM()函数返回NULL
值。
-- 查询各个部门的工资总和
select emp_dept, sum(salary) from emp group by emp_dept;
-- 查询开发部的工资总和
select emp_dept, sum(salary) from emp where emp_dept='开发部' group by emp_dept;
分页查询
-
引出分页
数据库中有大量符合搜索条件的数据,但是我们没有必要一次性全部展示,一来查询耗时,二来网络传输耗时,因此我们使用分页展示。
-
语法
-- offset 起始行数,从 0 开始计数,如果省略,默认就是 0 -- size 每页展示的记录数 limit offset,size
-
案例和公式
-- 每页展示三条员工记录,查询第一页 select * from emp limit 0,3 -- 查询第二页 select * from emp limit 3,3 -- 查询第三页 select * from emp limit 6,3
公式(记住即可)
找出当前页数和起始行数之间的规律
起始行数 start=(currPage-1)*size
- currPage 当前页数
- size 每页展示的记录数
注意:limit 语法是mysql的方言,其它数据库,对于分页有不同的实现方式。
-- 查询员工表的第3页数据,每页展示3条数据
start=(currPage-1)*size=(3-1)*3=6
select * from emp limit 6,3
扩展:
用 union/union all来连接结果集
如果想选择其他几个表中的行或从一个单一的表作为一个单独的结果集行的几个集会,那么可以使用的UNION。
UNION 用于合并两个或多个 SELECT 语句的结果集,并消去表中任何重复行。如果允许重复的值,请使用 UNION ALL。
我们来创建一个场景,学生表和教师表
create table teacher(
id int primary key auto_increment,
teacher_name varchar(20),
teacher_city varchar(20)
);
create table student(
id int primary key auto_increment,
student_name varchar(20),
student_city varchar(20)
);
insert into teacher(teacher_name, teacher_city) values('赵大', '武汉');
insert into teacher(teacher_name, teacher_city) values('陈二', '鄂州');
insert into teacher(teacher_name, teacher_city) values('张三', '襄阳');
insert into student(student_name, student_city) values('李四', '宜昌');
insert into student(student_name, student_city) values('王五', '恩施');
insert into student(student_name, student_city) values('钱六', '黄石');
insert into student(student_name, student_city) values('周七', '孝感');
我们用两个查询分别取得两个表的结果集,然后连接。
-- 举个栗子
select * from teacher
union
select * from student;
注意:
1、UNION 结果集中的列名总是等于第一个 SELECT 语句中的列名
2、UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。union只关注数据类型,数据业务含义是否相同不管。
如果要获取老师和学生来自哪些城市,则
select teacher_city from teacher
union
select student_city from student;
我们再插入3条记录
insert into student(student_name, student_city) values('周七1', '武汉');
insert into student(student_name, student_city) values('周七2', '武汉');
insert into student(student_name, student_city) values('周七3', '武汉');
比较一下3句sql
select * from teacher
union
select * from student;
select teacher_city from teacher
union
select student_city from student;
select teacher_city from teacher
union all
select student_city from student;
union会将结果集去重,它比较结果集中的全部字段,所有字段都相同的将被去除。union all 不去重。
union的用法及注意事项
union:联合的意思,即把两次或多次查询结果合并起来。
要求:两次查询的列数必须一致
推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样
可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。
如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并, 最终只保留一行。也可以这样理解,union会去掉重复的行。
如果不想去掉重复的行,可以使用union all。
如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。
select emp_dept, sum(salary) from emp group by emp_dept
union
select emp_dept, sum(salary) from emp group by emp_dept
order by emp_dept desc;
--或者这样
(select emp_dept, sum(salary) from emp group by emp_dept)
union all
(select emp_dept, sum(salary) from emp group by emp_dept)
order by emp_dept desc;
蠕虫复制
什么是蠕虫复制:在已有的数据基础之上,将原来的数据进行复制,插入到对应的表中
语法格式:INSERT INTO 表名1 SELECT * FROM 表名2;
作用:将表名2
中的数据复制到表名1
中
具体操作:
- 创建student2表,student2结构和student表结构一样
CREATE TABLE student2 LIKE student;
- 将student表中的数据添加到student2表中
INSERT INTO student2 SELECT * FROM student;