目录
搞定mysql--CURD操作,细节比较多,不难,贵在多多练
1、Create--创建
(1)单行插入 / 全列插入
(2)插入否则替换
(3)替换
2、Retuieve--select
1)全列查询
2)指定列查询
3)重命名列名
4)进行计算
5)去重
3、where条件
4、比较运算符
5、逻辑运算符
and关键字
or关键字
in 关键字
模糊匹配like
列与列比较
6、order by
7、limit关键字
8、Update(更新)
9、Delete(删除)
1)删除清空表
2)截断表
10、插入查询结果
11、聚合函数
(1)count函数
(2)sum函数
(3)avg函数
(4)max函数
(5)min函数
12、分组聚合函数--group by
13、having关键字
having 和 where的区别?
14、实战链接
表的增删查改:CURD:Create(创建)、Retieve(读取)、Update(更新)、Delete(删除)
1、Create--创建
(1)单行插入 / 全列插入
create table stu(
id int,
name varchar(32),
gender char(2)
);
单行插入
insert into stu (id, name) values (1,'张三');
多行插入
insert into stu (id, nmae, gender) values (2,'李四', '男'),(3,'王五', '女');
values前的括号() 可有可无
没有括号,表示全部插入;有括号,表示插入对应列
(2)插入否则替换
注意:如果主键冲突 / 唯一键冲突则不能插入
插入一条数据:
如果数据原先不存在 ,插入
如果存在,修改更新数据
有三种情况:
原先存在,更新数据和原先数据一样,影响0行
原先存在,更新数据和原先数据不一样,需更新,影响2行
原先不存在,插入数据,影响一行
insert into stu (id, name, gender)
values(1, '李四', '男')
on duplivate key update
name = '蔡坤';
在 MySQL 中,当主键或唯一索引冲突时,on duplicate key子句会被触发:如果在插入过程中遇到主键冲突(即 id 列的值为 1 的记录已经存在),则执行后面的更新操作,即将 name 列的值更新为 '蔡坤'。
(3)替换
如果主键 / 唯一键有冲突,删除原来一整行,插入新数据;影响2行
如果主键 / 唯一键不冲突,插入新数据;影响1行
replace into stu(id, name, gender) values (1, '李四', '男');
如果 id = 1 的记录不存在:
replace into 将插入一条新记录:(1, '李四', '男')。
如果 id = 1 的记录已经存在:原有的记录会被删除,然后插入新的记录:(1, '李四', '男')。
这意味着,如果存在其他字段的值,它们将被丢失,因为整行被删除再插入。
2、Retuieve--select
1)全列查询
select * from stu;
不建议*进行查询,因为传输数据量巨大
2)指定列查询
将指定列所有数据取出
select 属性列名... from table_name;#可带多个列
select id, name from stu;
3)重命名列名
select lod_name1 as new_name1 , lod_name2 as new_name2... from table_name;#as可以省略
select id as 学号, name as 名字 from stu;
4)进行计算
select 常数表达式 from table_name;
会将计算结果加入到所查询表中
也可以很灵活的使用:(例如所有的成绩之和,高数、线代、概率论的总分)
select 高数+线代+概率论 as 总分 from table_name;
select math + english as 总分 from stu;
5)去重
#对列的所有数据进行去重,可以同时去重多列
select distinct 列名.... from table_name;
示例:
select distinct id distinct name from table_name;
3、where条件
跟在查询后面,作为查询的筛选条件
select * from students where gender = '男' and age > 18;
where后跟计算表达式:计算总分小于200分的人
select id, name, (math + science + english) as total from stu
where total_score < 200;#此语句是错误的!
mysql语句执行顺序:将数据已经拿出来了,再对该数据列重命名
如果在查询的同时,对属性列语文 + 数学 + 英语进行重命名 为总分
然后此时再去where条件查询 总分列 是不对的
因为表中没有总分这个列
改名并没有在实际的表中增加一个总分的列,只是展示的时候进行了格式化
4、比较运算符
注意:null不可比较,null不是0,不可比较
一般判断null,使用is null / is not null
null不参与比较,如果参与比较,结果都是null
null也不参与计算,如果参与计算,结果都是null
运算符 | 符号 | 说明 |
---|---|---|
等于运算符 | = | 判断两个值是否相等。 |
不等于运算符 | != 或 <> | 判断两个值是否不相等。 |
大于运算符 | > | 判断左侧的值是否大于右侧的值。 |
小于运算符 | < | 判断左侧的值是否小于右侧的值。 |
大于或等于运算符 | >= | 判断左侧的值是否大于或等于右侧的值。 |
小于或等于运算符 | <= | 判断左侧的值是否小于或等于右侧的值。 |
IS NULL | IS NULL | 判断值是否为 NULL。 |
IS NOT NULL | IS NOT NULL | 判断值是否不为 NULL。 |
示例:18岁以上的男学生
select * from students where gender = '男' and age > 18;
5、逻辑运算符
运算符 | 符号 | 说明 |
---|---|---|
与运算符 | AND | 当且仅当两个条件都为真时,结果为真。 |
或运算符 | OR | 只要至少有一个条件为真,结果就为真。 |
非运算符 | NOT | 取反运算符,条件为真则结果为假,条件为假则结果为真。 |
逻辑异或运算符 | XOR | 当两个条件不同时,结果为真;当两个条件相同时,结果为假。 |
示例:
and关键字
语文成绩在[80,90]之间的所有学生
select Chinese from stu where Chinese >=80 and Chinese <=90;
or关键字
数学成绩是59 或者 89的同学
select * from stu where math=59 or math=89;
in 关键字
数学成绩在58 或 78 或 88 或98的同学
select * from stu where math in (58,78,88,98);
模糊匹配like
%匹配任意多个字符
_匹配一个字符
现在有一个人,你只记得他姓孙,但是具体并不知道是孙什么,于是:
selelct * from people where name like‘孙%’;
现在有一个人,你记得他姓孙,而且,是两个字,于是:
select * from stu where name like “sun_”;
列与列比较
数学成绩好于英语成绩的同学
select * from stu where math > english;
6、order by
升序、降序表格(null比任何值都小)
同学按照数学成绩升序排序
select math from stu order by math asc;
同学按照数学成绩降序排序
select math from stu order by math desc;
重命名之后,可以查询
为什么?
因为排序,首先是得有了数据,才可以查询
本质是因为语句的执行顺序的不同
这里的执行顺序是,先执行重命名再排序
7、limit关键字
limit n;#从表开始,连续读n行
limit m,n;#下标从m开始读取,读到n行
limit n offset m;#下标从m开始,读取n行
有什么用?方便查看资料
limit本质是一种显示。
select * from stu limit 5, 10;#从第5个开始,往后查找10个
8、Update(更新)
对查询到的结果进行列值更新
一般来说,要和where条件判断一起用
否则就会将整个列的值更新,这是不符合逻辑的
因此update一定要慎用慎用!
示例:
将孙悟空的语文成绩更新成80分
update stu set chinese=80 where name=‘孙悟空;
将总成绩倒数前三的同学数学成绩+30
update stu set math=math+30 order by chinese+english+math asc limit 3;
#拿到前三个总分(默认升序)
#对前三个进行数学=30分
9、Delete(删除)
删除是对表的内容处理,表的结构不受影响
delete from stu where name='李四';#删除对应行delete from stu;#删除所有内容
删除孙悟空的考试成绩
delete from students where name = '孙悟空';
1)删除清空表
不会影响自增设定
示例:
delete from stu;
2)截断表
会直接清空表的内容,
同时自增值会变为0
不走事务,直接清空
也就是不做日志备份
truncate table stu;
10、插入查询结果
查询一个表的结果,并将结果插入到一个新的表当中
int into table_name [列名] select [列名] from table_name` where ...;ser
示例:只插入语文成绩及格的学生
insert into stu(id, name, chinese_score, english_score)
select id, name, chinese_score, english_score
from stu
where chinese_score >= 60;
#只插入语文成绩及格的学生
重命名表名:
rename table old_table_name to new_table_name;
创建一个表B
表B的结构和表A的结构一样
cereate table table_B like table_A;
11、聚合函数
函数名 | 功能 | 语法 | 示例 |
---|---|---|---|
count() | 计算行数或非 null 值的数量 | count(column_name) 或 count(*) | select count(*) from students; |
sum() | 计算某列值的总和 | sum(column_name) | select sum(salary) from employees; |
avg() | 计算某列值的平均值 | avg(column_name) | select avg(score) from tests; |
min() | 返回某列的最小值 | min(column_name) | select min(age) from persons; |
max() | 返回某列的最大值 | max(column_name) | select max(price) from products; |
group_concat() | 将分组中的多个值连接成一个字符串 | group_concat(column_name separator 'separator') | select group_concat(name) from students group by class; |
count(distinct) | 计算不同值的数量 | count(distinct column_name) | select count(distinct department) from employees; |
(1)count函数
1)统计一个表有多少行,null不影响
select count(*) from table_name;
2)统计某一个列多少行
select count(某列) from table_name;
示例:
统计数学成绩,不重复:
select count(distinct math) from stu;
和where组合:查询英语成绩不及格的人数
select count(*) from exam_result where English<60;
(2)sum函数
select sum(某列) from table_name;
示例:查询数学品均分
select sum(math) / count(math) from stu;
清屏:
system clear;
(3)avg函数
求平均函数
示例:求成绩平均分
select avg(math+english+chinese) as 平均分 from stu;
(4)max函数
求最大函数
示例:求数学最高分
select max(math) from stu;
(5)min函数
求最小函数
示例:求数学最低分
select min(math) from stu;
12、分组聚合函数--group by
在 select 中使用 group by 字句可以对指定列进行分组查询
select column1,Column2,... from table_name group by column;
举个例子:
将表从文件系统中导入到数据库系统中:
source 文件路径;
该数据库下有三个1表:
员工、部门、薪资等级
如何显示每个部门的最高工资和平均工资?根据部门分组
select deptno,max(sal) as 最高工资,avg(sal)as 平均 from emp group by deptno;
分组,如何理解?
1、指定列名,就是用单列的不同行的数据进行分组
(例如以性别进行分组,就会被分成男 和 女两组)
(以code进行分组,就会被分成A、B、C、D四组)
2、每一个组内的条件都是一样的
3、分组就是把一张表在逻辑上拆成了多个子表,然后对各自的子表进行聚合统计
很简单,就是把表分开了,成一个一个组,然后一个个组自己统计
示例:
1、显示每一个部门的每种岗位的平均工资和最低工资
select deptno, job ,avg(sal)avg_sal, min(sal)min_sal from group by deptno,job;
#先分组,再聚合
group by deptno,job;#先按deptno分组,再按job分组
选择的分组列,必须是大家都有共同的属性,或者属性不同,无法进行聚合
一般只有再group by后面具体出现的列,才可以在前面出现,跟在select后面,聚合展示
2、统计每一个部门的平均工资
select avg(sal) as avg_sal, deptno from emp group by deptno;
3、低于2000的部门抽取出来
select avg(sal) deptno_avg from emp group by deptno having deptnoavg <2000;
13、having关键字
是对数据聚合后的数据进行条件筛选
类似于where
只是场景用于聚合后的数据
having 和 where的区别?
having可以使用在where的地方
但是where不能使用在having的地方
如何理解?
可以理解为:
整张表可以理解为就是一个组
只是这个组比较大
因此,我们对于having的理解就是:将一个大的表分成多个小的表
但是where是具体的对某一个列做条件筛选
因此:where和having条件筛选的阶段不同 / 时机不同
对表的理解:不要单纯的认为,只有磁盘上表结构导入到mysql的表才叫做表
而是:在mysql中中间筛选出来的表、最终结果,都可以逻辑上视为一个表
于是,在这样“MYSQL一切皆表”统一视角的观点下,
只要我们能够处理好一张表的CURD,
所有的MYSQL场景,我们全部都能用统一的方式进行处理
下面举一个例子:
select deptno, job. avg(sal) avg——sal from empwhere ename != 'xxx'
group by deptno, job
having myavg < 2000;
14、实战链接