博客主页:花果山~程序猿-CSDN博客
文章分栏:Linux_花果山~程序猿的博客-CSDN博客MySQL之旅_花果山~程序猿的博客-CSDN博客Linux_花果山~程序猿的博客-CSDN博客
关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长!
目录
一,表内容的插入,删除,修改
插入
插入是否更新
替换式插入
查询
where
结果排序(order by)
结果分页(limit)
修改
update*
删除
delete*
truncate*
向新表插入查询结果
二,聚合统计函数
group by & having
结语
嗨!收到一张超美的风景图,愿你每天都能顺心!
一,表内容的插入,删除,修改
插入
常见的插入我们已经熟练使用过了,如b连续插入表:
insert [ into ] table_name [列名1,列明2] values (内容1, 内容2,...) , (内容1, 内容2)...;
插入是否更新
由于 主键 或者 唯一键 对应的值已经存在而导致插入失败,因此对已存在的数据进行修改。
insert [into] ... on duplicate key update 列名=新内容 ...;
检测此次特殊的插入操作结果:
-- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,并且数据已经被更新
例如,下面就是有冲突数据,将已经存在的数据进行更新:
替换式插入
replace [into] table_name[列名1,列名2...] value (内容1,内容2...);
检测插入结果:
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,删除后重新插入
示例如下:
查询
语法:
SELECT
[DISTINCT] {* | {column [, column] ...}
[FROM table_name]
[WHERE ...]
[ORDER BY column [ASC | DESC], ...]
LIMIT ...
我们经常用的比如 * from , where,剩余的我们通过例子进行了解。
为查询操作,制作实验库:
-- 创建表结构
CREATE TABLE exam_result (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL COMMENT '同学姓名',
chinese float DEFAULT 0.0 COMMENT '语文成绩',
math float DEFAULT 0.0 COMMENT '数学成绩',
english float DEFAULT 0.0 COMMENT '英语成绩'
);-- 插入测试数据
INSERT INTO exam_result (name, chinese, math, english) VALUES
('唐三藏', 67, 98, 56),
('孙悟空', 87, 78, 77),
('猪悟能', 88, 98, 90),
('曹孟德', 82, 84, 67),
('刘玄德', 55, 85, 45),
('孙权', 70, 73, 78),
('宋公明', 75, 65, 30);
首先我们需要了解的是 select 的特殊用法,如:
select + 表达式
(注:从上面单独列名的查询可以看出,加上在linux指令对 * 的理解,* 是代表全部,任一的意思。说到 select * ,我们就需要注意一下,在未来我们工作时,mysql的服务一般在远端,需要通过网络传输,而一个中小型公司的数据库的数据量少说都是几千万行的数据,如果select *,则会消耗大量的网络资源,因此select * 一般学习时用用就好。
where
where 关键字在sql 类似于 编程语言中if语句,是一个判断语句。
常见的语法:
select ... from table_name where []
下面我们看看mysql中有那些逻辑语句:
就当做C语言来学即可,需要多注意null的比较,0表示有效,null则表示未填入。
查询案例:
1. 英语不及格的同学及英语成绩 ( < 60 )
select name, english from exam_result where english < 60;
2. 语文成绩在 [80, 90] 分的同学及语文成绩
select name , chinese from exam_result where chinese between 80 and 90 ;
3. 数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
select name, math from exam_result where math=58 or math=59 or math=98 or math=99;
select name , math from exam_result where math in(58,59,98,99);
4. 姓孙的同学 及 孙某同学
select name from exam_result where name like '孙%';
select name from exam_result where name like '孙_';
5. 语文成绩好于英语成绩的同学
select name from exam_result chinese > english;
6. 总分在 200 分以下的同学
select name, math + chinese + english as total from exam_result where math + chinese + english < 200;
这里我们需要再次了解一下select,如图:
7. 语文成绩 > 80 并且不姓孙的同学
select name , chinese from exam_result where chinese > 80 and name not like '孙%'
ke '孙%';
8. 孙某同学,否则要求总成绩 > 200 并且 语文成绩 < 数学成绩 并且 英语成绩 > 80
select name, chinese, math, english , chinese + math+english as total-> from exam_result-> where name like '孙_' or (chinese + math+english > 200 and chinese < math and english > 80);
结果排序(order by)
语法:
select ... from table_name [where ...] order by column [desc | asc]
mysql语句执行顺序,先通过where筛选出表数据,结果可以再进行处理(排序),最后展示。
比如下面这个例子:
select name, math from exam_result where name like '孙%' or name like '曹%'order by math desc;
结果分页(limit)
并没有分页,只是选择性的每次只展示一些数据。
语法:
select ... from ... [where ...] [order by ...] limit s , n;
s表示开始的行,以0作为起始行下标;n表示展示行的步数。
.... limit n; //则默认从0下标行开始
案例:
修改
update*
update这个语句的使用比较危险,使用示例如下:
将孙悟空的数学成绩变成80分:
update exam_result set math = 80 where name ='孙悟空';
如果我们忘记搭配 where 使用,那么 math这列的数据,全部设置为80,直接破坏其余数据,因此Update的使用风险很大,对单个数据的修改,宁愿使用insert的插入式更新。
不添加 where 就是对全表进行操作,需谨慎。
删除
delete*
语法:
delete [table] table_name;
清楚孙悟空的数据
delete from exam_result where name = '孙悟空';
区别于drop删除表,delete则是清空表,保留自增值,请看下面例子:
实验表:
-- 准备测试表
CREATE TABLE for_delete (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);-- 插入测试数据
INSERT INTO for_delete (name) VALUES ('A'), ('B'), ('C');
截断表 (truncate)
语法:
trunvcate [table] table_name;
相对于delete,有以下区别:
向新表插入查询结果
语法:
insert [into] table table_name1 ... select ...
情景:获取去重后的表
实验表创建:
CREATE TABLE duplicate_table (id int, name varchar(20));INSERT INTO duplicate_table VALUES
(100, 'aaa'),
(100, 'aaa'),
(200, 'bbb'),
(200, 'bbb'),
(200, 'bbb'),
(300, 'ccc');
曾经我们通过distinct来处理结果,达到去重的效果,
但这不是一个新表,我们无法进行后续的数据操作。因此,通过下面几步在mysql中来完成一个去重表替换旧表的操作。
1. 创建一张相同结构的空表
create table no_duplicate_table like duplicate_table;
2. 将去重后的查询结果插入空表
insert into no_duplicate_table select distinct * from duplicate_table;
3. 最后重命名,实现原子去重操作
rename table duplicate_table to old_duplicate_table, no_duplicate_table to duplicate_table;
怎么理解该去重的原子操作?答:在重命名前,在旧数据表无法察觉的情况下,已经创建了替换副本,由于重命名本质上就是修改文件名,也就是调用move指令,修改文件名,因此等再次使用数据表时,已经完成替换,属于原子操作。
二,聚合统计函数
函数如下:
案例:
1.统计参与的同学数
2. 统计平均总分
如何理解聚合统计函数? 答:我们得以整个表的角度来看,例如:min(math),在获取每一行的math时,会经过min函数判断是否比历史最小值小。因此,
count 是对查询结果的行个数进行统计;
sum 则是统计每一行查询出的结果进行统计,得出表级别的数据;
group by & having
select column1, column2, .. from table group by column1, column2;
(注:group by 可以用于去重,对比distinct,group by在大表中,效率会更高,用法 select 字段 .. group by 字段)
准备一个测试表,如下:
- EMP员工表
- DEPT部门表
- SALGRADE工资等级表
DROP database IF EXISTS `scott`;
CREATE database IF NOT EXISTS `scott` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;USE `scott`;DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (`deptno` int(2) unsigned zerofill NOT NULL COMMENT '部门编号',`dname` varchar(14) DEFAULT NULL COMMENT '部门名称',`loc` varchar(13) DEFAULT NULL COMMENT '部门所在地点'
);DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (`empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',`ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',`job` varchar(9) DEFAULT NULL COMMENT '雇员职位',`mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',`hiredate` datetime DEFAULT NULL COMMENT '雇佣时间',`sal` decimal(7,2) DEFAULT NULL COMMENT '工资月薪',`comm` decimal(7,2) DEFAULT NULL COMMENT '奖金',`deptno` int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (`grade` int(11) DEFAULT NULL COMMENT '等级',`losal` int(11) DEFAULT NULL COMMENT '此等级最低工资',`hisal` int(11) DEFAULT NULL COMMENT '此等级最高工资'
);insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (deptno, dname, loc)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (deptno, dname, loc)
values (30, 'SALES', 'CHICAGO');
insert into dept (deptno, dname, loc)
values (40, 'OPERATIONS', 'BOSTON');insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7844, 'TURNER', 'SALESMAN', 7698,'1981-09-08', 1500, 0, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);insert into salgrade (grade, losal, hisal) values (1, 700, 1200);
insert into salgrade (grade, losal, hisal) values (2, 1201, 1400);
insert into salgrade (grade, losal, hisal) values (3, 1401, 2000);
insert into salgrade (grade, losal, hisal) values (4, 2001, 3000);
insert into salgrade (grade, losal, hisal) values (5, 3001, 9999);
如何显示每个部门的平均工资和最高工资
显示每个部门的每种岗位的平均工资和最低工资
显示平均工资低于 2000 的部门和它的平均工资 , having和 group by 配合使用,对 group by 结果进行过滤。
如何区别 where & having?
( 面试题 )SQL 查询中各个关键字的执行先后顺序 from > on> join > where > group by > with > having > select > distinct > order by > limit
结语
本小节就到这里了,感谢小伙伴的浏览,如果有什么建议,欢迎在评论区评论,如果给小伙伴带来一些收获,请动动你发财的小手点个免费的赞,你的点赞和关注永远是博主创作的动力源泉。