MySQL基本查询

1. create

语法:

insert [into] table_name [(column [, column] ...)] values (value_list) [, (values_list)]...

[]里面的内容可以省略,values两侧平衡(可理解为扁担),左侧表示要向哪列插入,右侧表示插入的数据

1.1 单行数据 + 全列插入

创建一个学生表:

mysql> create table students (
    -> id int unsigned primary key auto_increment,
    -> sn int unsigned unique key,
    -> name varchar(20) not null,
    -> telephone varchar(32) unique key
    -> );

一次插入一行数据:

mysql> insert into students(sn, name, telephone) values (23402101, '张三', '2024001');
mysql> insert into students values (10, 23402110, '李四', '2024010');	# 全列插入

values左侧忽略时就表明要进行全列插入,每一列都要指定数据

image-20240427204210803

1.2 多行数据 + 指定列插入

mysql> insert into students values (11, 23402111, '王五', '2024011'), (12, 23402112, '赵六', '2024012');

values右侧用逗号隔开,表明插入多行数据

image-20240427210520151

1.3 插入更新

mysql> insert into students values (12, 23402122, '田七', '2024022');	#主键冲突
ERROR 1062 (23000): Duplicate entry '12' for key 'PRIMARY'
mysql> insert into students values (13, 23402113, '田七', '2024012');	# 唯一键冲突
ERROR 1062 (23000): Duplicate entry '2024012' for key 'telephone'

当插入时出现冲突的时候,可采用同步更新操作,语法:

insert into  ... on duplicate key update column = value [, column = value] ...
mysql> insert into students values (12, 23402122, '田七', '2024022') 
    -> on duplicate key update sn=23402122, name='田七', telephone='202422';

-- 0 row affected: 表中有冲突数据,但冲突数据的值和 update 的值相等
-- 1 row affected: 表中没有冲突数据,数据被插入
-- 2 row affected: 表中有冲突数据,并且数据已经被更新

可采用select row_count()查看受影响的行数

image-20240427213328406

1.4 插入替换

如果主键或者唯一键没有冲突,则直接插入;

如果主键或者唯一键冲突,先删除,再插入:

mysql> replace into students (sn, name, telephone) values (234021015, '老八',  2024015);
Query OK, 1 row affected (0.01 sec)

mysql> replace into students (sn, name, telephone) values (234021015, '小八',  2024015);
Query OK, 2 rows affected (0.00 sec)

image-20240506140350086

2. retrieve

mysql> create table exam_ret(
    -> id int unsigned primary key auto_increment,
    -> name varchar(20) not null,
    -> chinese float default 0.0 comment '语文成绩',
    -> math float default 0.0 comment '数学成绩',
    -> english float default 0.0 comment '英语成绩'
    -> );
mysql> insert into exam_ret (name, chinese, math, english) values 
    -> ('张三', 88, 84, 77),
    -> ('李四', 75, 91, 66),
    -> ('王五', 45, 82, 73),
    -> ('赵六', 94, 42, 51),
    -> ('田七', 62, 67, 98);

2.1 select列

2.11 全列查询
mysql> select * from exam_ret;

image-20240506141645467

*表示通配,在实际并不推荐采用*进行全列查询

  1. 数据库服务一般在服务器上;
  2. 线上服务器数据库里面存储的数据量非常大
2.12 指定列查询
mysql> select name, math from exam_ret;

image-20240506143432306

2.13 查询字段为表达式
mysql> select name, math, chinese+math+english from exam_ret;

image-20240506143627330

也可也将表达式名称命名

mysql> select name, math, chinese+math+english as total from exam_ret;

image-20240506143807823

mysql> select name 姓名, math 数学, chinese+math+english 总分 from exam_ret;

image-20240506144149901

2.14 结果去重
mysql> select distinct chinese from exam_ret;

image-20240506144613805

2.2 where条件

比较运算符:

运算符 说明
>, >=, <, <= 大于,大于等于,小于,小于等于
= 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=> 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <> 不等于
BETWEEN a0 AND a1 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1)
IN (option, …) 如果是 option 中的任意一个,返回 TRUE(1)
IS NULL 是 NULL
IS NOT NULL 不是 NULL
LIKE 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符

逻辑运算符:

运算符 说明
AND 多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR 任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT 条件为 TRUE(1),结果为 FALSE(0)
2.21 各种成绩查询

查找成绩不及格的同学:

mysql> select name, chinese from exam_ret where chinese<60;
mysql> select name, math from exam_ret where math<60;
mysql> select name, english from exam_ret where english<60;

image-20240506154328658

查找语文成绩在[80,100]的同学:

mysql> select name, chinese from exam_ret where chinese>=80 and chinese<=100;
mysql> select name, chinese from exam_ret where chinese between 80 and 100;

image-20240506154759810

查找指定英语成绩:

mysql> select name, english from exam_ret where english=98 or english=97 or english=51;
mysql> select name, english from exam_ret where english in (98, 97, 51);

image-20240506155117329

查找姓张和张某:

mysql> select name from exam_ret where name like '张%';	#姓孙
mysql> select name from exam_ret where name like '张_';	#孙某

image-20240506160020496

查找英文成绩好于英语成绩的同学:

mysql> select name, chinese, english from exam_ret where chinese > english;

image-20240506160245145

查找总分小于225的同学:

mysql> select name, chinese + math + english total from exam_ret where total<225;
ERROR 1054 (42S22): Unknown column 'total' in 'where clause'

在上面的sql语句中,执行顺序是:

  1. 先执行from,要知道在哪个表当中筛选数据;
  2. 再执行where,要知道筛选的条件,拿着条件去筛选;
  3. 最后拿着条件去指定表里面的指定列筛选

所以这里报错不认识这个total别名

mysql> select name, total from exam_ret where chinese + math + english total<225;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'total<200' at line 1

上面这样也不行,因为对列做重命名,已经是最后一步了,将数据拿完,最后改一下名字

mysql> select name, chinese+math+english total from exam_ret where chinese+math+english<225;

image-20240506161731651

查找语文成绩大于80且不姓张的同学:

mysql> select name,chinese from exam_ret where chinese>80 and name not like'张%';

image-20240506162231153

查找张某同学,其他的同学成绩必须>225且英语>80:

mysql> select name, chinese, math, english, chinese+math+english total from exam_ret where name like '张_' or (chinese+math+english>225 and english>80);

image-20240506163032780

2.22 null的查询

image-20240506163638496

mysql> select * from t11 where name is null;
mysql> select * from t11 where name is not null;

image-20240506163947486

null表示没有,' '表示有,但是是空串

2.3 结果排序

语法:

select ... from table_name [where ...] order by column [asc|desc], [...]
#asc 为升序(默认为asc)
#desc 为降序

如果有nullnull视为比任何值都小

语文成绩升序排序:

mysql> select name,chinese from exam_ret order by chinese;

image-20240506164927751

语文成绩升序、数学成绩降序、英语成绩降序:

这个意思是,如果语文成绩一样,按数学降序排序;如果语文、数学成绩一样,按英语降序排序

mysql> select name, chinese, math, english from exam_ret order by chinese asc, math desc, english desc;

image-20240506165844810

查询总分,降序排序

mysql> select name, chinese+math+english as total from exam_ret order by total desc;

image-20240506192701983

为什么where后面无法使用别名,而这里可以使用:

在排序之前,是要先有合适的数据

  1. 先执行from,知道在哪个表
  2. 如果有where子句,再执行where,拿到筛选条件
  3. 筛出要的数据
  4. 筛选出的数据进行排序

order byname, chinese+math+english as total语句后面,所以order by后面可以跟别名

查询姓张或者姓王的同学数学成绩,数学成绩降序:

mysql>  select name, math from exam_ret where name like '张%' or name like '王%' order by math desc;

image-20240506194237638

2.4 筛选分页结果

mysql> select * from exam_ret limit 5;	#从表的开始连续读取5行
mysql> select * from exam_ret limit 3,5;	#从指定位置(3, 下标从0开始)开始,连续读取5行

image-20240506194534466

也可也这样使用,更加明确

mysql> select * from exam_ret limit 4 offset 1;	#从1号下标开始, 连续读取4行

image-20240506194853393

对未知的表进行查询,最后加上limit 1,防止数据过大,导致全表数据库卡死

只用在数据准备好了,才需要显示,limit的本质功能就是"显示",它的执行阶段会更加靠后

3. update

修改指定同学成绩:

mysql> update exam_ret set english=100 where name='张炎炎';

image-20240506205534978

多列修改:

mysql> update exam_ret set english=21,math=100 where name='张焱焱';

image-20240506205830186

总分倒数前三的数学加上25分:

mysql> update exam_ret set math=math+30 order by chinese+math+english asc limit 3;

image-20240506210432455

所有同学数学成绩减10分:

mysql> update exam_ret set math=math-10;

image-20240506210718999

当没有筛选条件的时候,要谨慎使用update,一个误操作,直接修改了全部的数据

4. delete

删除指定同学的成绩:

mysql> delete from exam_ret where name='老八';

image-20240506211148107

删除整张表的数据:

删除表结构和删除表的数据不一样!

delete from t11;

image-20240506211538419

这里删除整张表的数据,并不会将自动增量的值并不会清零,如果想将自动增量的值清零,可采用截断表

image-20240506212415709

mysql> truncate for_truncate;

image-20240506212656001

deletetruncate区别:

  • delete会走事务,truncate不走事务,即truncate不会将操作痕迹记录在日志当中
    由于不走事务,所以truncate会比delete稍微快一点
  • truncate只能对整表操作
  • truncate会重置auto_increment

5. 插入查询结果

mysql> create table duplicate_table (
    -> id int,
    -> name varchar(20)
    -> );
    
mysql> insert into duplicate_table values (2024,'aaa');
mysql> insert into duplicate_table values (2024,'aaa');
mysql> insert into duplicate_table values (2025,'bbb');
mysql> insert into duplicate_table values (2025,'bbb');
mysql> insert into duplicate_table values (2026,'ccc');

当表中有重复数据的时候,可采用:

mysql> select distinct * from duplicate_table;

image-20240507085400687

这样在显示的时候数据已经去重,可是并未影响到表中的数据

如果想得到没有重复数据的表,可以将该表的去重查询结果插入到另一个表当中,然后将原表重命名,最后将新表改为原始表的名字

mysql> create table no_duplicate_table like duplicate_table;

插入查询结果:

mysql> insert into no_duplicate_table select distinct * from duplicate_table;

image-20240507090404476

重命名:

mysql> rename table duplicate_table to old_duplicate_table,
    -> no_duplicate_table to duplicate_table;

image-20240507090734104

为什么是rename方式进行:

将一个文件上传到Linux中,在上传的过程中一直在写入,这个过程并不是原子的,所以会上传到一个临时目录下,当然全部上传完毕之后,最后再统一将这个文件move到指定目录,move操作的原子的。

rename也是同理,等一切就绪了,然后统一放入、更新、生效等

6. 聚合函数

函数 说明
COUNT 返回匹配查询条件的行数。
SUM 返回匹配查询条件的列的总和。
AVG 返回匹配查询条件的列的平均值。
MAX 返回匹配查询条件的列的最大值。
MIN 返回匹配查询条件的列的最小值。

6.1 无分组聚合

示例还是采用之前的exam_ret

统计总共有多少个学生:

mysql> select count(*) from exam_ret;

image-20240507092917914

count(6)并不是指特定的列或条件,它只是一个值,mysql会将它解释为计算所有非NULL值为6的数量

统计语文不同成绩个数:

mysql> select count(distinct chinese) from exam_ret;

image-20240507093408411

count是对结果做聚合,就一个数字,所以要在聚合之前去重,再聚合

统计成绩总分:

mysql> select sum(math) as math_ret from exam_ret;

image-20240507093830415

统计平均分:

mysql> select avg(english) as english_avg from exam_ret;

image-20240507094135347

统计不及格人数:

mysql> select count(math) as math_fail from exam_ret where math<60;

image-20240507094416874

最高分和最低分:

mysql> select min(chinese) ret from exam_ret;
mysql> select max(chinese) ret from exam_ret;

image-20240507094901462

6.2 分组聚合

分组是对表当中的数据进行分组,然后根据分组再进行聚合统计

导入测试表(来自Oracle 9i):

mysql> source /path/scott_data.sql;

image-20240507111240285

  • dept部门表
  • emp员工表
  • salgrade工资等级表

显示每个部门的平均工资和最高工资:

mysql> select deptno, max(sal) sal_max, avg(sal) sal_avg from emp group by deptno;

image-20240507111658579

group by column,指定列名,实际分组是根据该列的不同行数据来进行分组的

分组条件deptno,组内一定相同,可以被聚合压缩

即分组就是把一张表按照条件在逻辑上拆成多个子表,然后对各自子表进行聚合统计

每个部门的每种岗位平均薪资和最低薪资:

mysql> select deptno, job, avg(sal) sal_avg, min(sal) sal_min from emp group by deptno, job;

image-20240507113007915

一般在group by当中出现的具体列名称才可以在select后面具体出现

还有一类就是聚合函数

平均薪资低于2000的部门和它的平均薪资:

  • 统计各部门平均工资:

    mysql> select deptno, avg(sal) sal_avg from emp group by deptno;
    

    image-20240507113516148

  • having配合group by使用,对结果进行过滤:

    mysql> select deptno, avg(sal) sal_avg from emp group by deptno having sal_avg<2000;
    

    image-20240507113654035

    havingwhere区别:

    • where是对具体的任意列进行条件筛选;
    • having对分组聚合之后的结果进行条件筛选

不是只有磁盘上的表结构导入到mysql,真实存在的表才叫表;中间筛选出来的、最终结果显示的,也是表,逻辑上的表,即可以理解为 mysql一切皆表

所以只要能处理好单表的crud,所有的sql场景都能够用统一的方式进行!

相关推荐

  1. MySQL基本查询 练习

    2024-05-11 17:54:05       31 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-11 17:54:05       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-11 17:54:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-11 17:54:05       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-11 17:54:05       20 阅读

热门阅读

  1. fastapi数据库连接池的模版

    2024-05-11 17:54:05       15 阅读
  2. D3.js实战:数据可视化高级技巧实例应用

    2024-05-11 17:54:05       16 阅读
  3. idea

    idea

    2024-05-11 17:54:05      15 阅读
  4. postman---认证(Certificates)是什么作用?

    2024-05-11 17:54:05       12 阅读
  5. git命令详解+使用样例

    2024-05-11 17:54:05       17 阅读
  6. 代码随想录训练营Day29:动态规划1

    2024-05-11 17:54:05       16 阅读
  7. 高德地图定位点缩放偏移问题

    2024-05-11 17:54:05       14 阅读
  8. 安卓实现连接wesokcet

    2024-05-11 17:54:05       16 阅读
  9. 类和对象的关系

    2024-05-11 17:54:05       14 阅读
  10. Mvcc 如何解决脏读、不可重复读问题

    2024-05-11 17:54:05       11 阅读
  11. 服务器白名单

    2024-05-11 17:54:05       11 阅读