目录

MySQL篇MySQL基本查询详解

【MySQL篇】MySQL基本查询详解


前言:

本篇主要讲述对于表 内容的增删查改及相关查询语句 :

**CRUD : Create(

创建

), Retrieve(

读取

)

Update(

更新

)

Delete

(删除)**



1,Create

语法:

insert into 表名  (指定列) values  (values1,values2,…)

示例:

  • 创建一张学生表

**mysql> create table students(

-> id int unsigned primary key auto_increment,

-> sn int not null unique comment ‘学号’,

-> name varchar(20) not null,

-> qq varchar(20) unique);**

1.1,单行数据+全列插入

  • 插入数据

注意在这里插入的时候也可以不指明id,因为我们定义了auto_increment属性,mysql会使用默认的值自增。

mysql> insert into students values (1,101,‘张三’,1111);

mysql> insert into students values (2,102,‘李四’,11222);

https://i-blog.csdnimg.cn/direct/3dc3af7d964d4448a56b7fb9365bd00c.png

  • 查看插入结果

select * from students;

https://i-blog.csdnimg.cn/direct/8efe367f47e94cd0a4729d63d0928c16.png

1.2,单行数据+指定列插入

  • 指定列插入数据

mysql> insert into students  (sn,name,qq) values (103,‘李四’,11333);

mysql> insert into students (id,sn,name) values (10,104,‘王五’);

https://i-blog.csdnimg.cn/direct/819a7ab58d5244c38de644ac0313167b.png

https://i-blog.csdnimg.cn/direct/62858d8f980b47c9ba888151a4cca7ff.png

1.3,多行数据+全列插入

mysql> insert into students values (20,105,‘赵六’,2222) ,(21,106,‘田七’,3333);

https://i-blog.csdnimg.cn/direct/f07c7bf79b8e48efa120303916fb8f16.png

1.4,多行数据+指定列插入

mysql> insert into students (sn,name) values (116,‘北京’),(117,‘上海’);

https://i-blog.csdnimg.cn/direct/71c04375173642c3ad99818e7dee6a8e.png

1.5,插入否则更新

在插入数据的时候,由于 主键和唯一键 的存在,可能导致插入的数据已经存在而插入失败。

https://i-blog.csdnimg.cn/direct/387b9acdd54a449bb759781aae604752.png

如果需要更新,可以进行 更新 操作。也就是在插入数据时,如果不存在就直接插入,如果存在,发生冲突了,就将原来的数据更新为插入的数据。 这个和STL中的unordered_map类似,在使用[ ]的时候,如果存在就更新,如果不存在就插入。

语法:

insert  …… on duplicate key update column=value[……]

示例:

mysql> insert into students values (1,101,‘张三’,55555) on duplicate key update id=1,sn=101,name=‘张三’,qq=55555;

https://i-blog.csdnimg.cn/direct/22956649f03449a1aeacf2e270a84a76.png

在更新的时候也要保证不和其他值冲突。

https://i-blog.csdnimg.cn/direct/68d3a38e58884b3486cb8922d427d673.png

1.6,替换

替换replace与上面的插入更新类似,如果数据存在就替换,如果数据不存在就直接插入。

mysql> replace into students (sn,name) values (120,‘广州’);//不存在直接插入

mysql> replace into students (id,sn,name,qq)  values (1,101,‘苏州’,99999);//数据已经存在,则替换掉原数据

https://i-blog.csdnimg.cn/direct/132b9f8c466c4fd88f9a07a6404e6dfd.png

https://i-blog.csdnimg.cn/direct/7d36ab09075d476484a35f349c760cfd.png

https://i-blog.csdnimg.cn/direct/94b4bbb421024e72a933872698dcf5b8.png

2,Retrieve (读取)

首先创建一张学生成绩表,作为示例

**mysql> create table exam_result(

-> id int unsigned primary key auto_increment,

-> name varchar(20),

-> chinese int,

-> math int,

-> english int);**

https://i-blog.csdnimg.cn/direct/465a31efabf14826bf29a5fd499f113a.png

向表中插入一些数据:

mysql> insert into exam_result (name,chinese,math,english) values (‘孙悟空’,87,78,77);

mysql> insert into exam_result (name,chinese,math,english) values (‘猪悟能’,88,98,90);

mysql> insert into exam_result (name,chinese,math,english) values (‘曹孟德’,82,84,67);

mysql> insert into exam_result (name,chinese,math,english) values (‘刘玄德’,55,85,45);

mysql> insert into exam_result (name,chinese,math,english) values (‘孙权’,70,73,78);

mysql> insert into exam_result (name,chinese,math,english) values (‘宋公明’,75,65,30);

2.1,全列查询

**mysql> select *

from exam_result;**

https://i-blog.csdnimg.cn/direct/a8b1e8bd10134f3f87f60412aa3fb09a.png

通常情况 下不建议使用 * 进行全列查询

  • 查询的列越多意味着需要传输的数据量越大;
  • 可能会影响到索引的作用。(索引在后面更新)

2.2,指定列查询

select 筛选的列名称 from 表名

示例:

**mysql> select id,name,math from exam_result;

mysql> select id,name,chinese  from exam_result;**

https://i-blog.csdnimg.cn/direct/0f224c753a07433a9b4f01ab770d6e48.png

2.3,查询字段为表达式

  • 表达式不包含字段

mysql> select id,name,math,10 from exam_result;

mysql> select id,name,math,10+10 from exam_result;

https://i-blog.csdnimg.cn/direct/c6f84fffef4a4ed4ae2312d9f249c142.png

  • 表达式中包含一个字段

mysql> select id,name,math+10 from exam_result;

https://i-blog.csdnimg.cn/direct/1460866aff44410a971bd5339b08a0ca.png

  • 表达式中包含多个字段

mysql> select id,name,math+chinese+english from exam_result;

https://i-blog.csdnimg.cn/direct/aea59883b3c143d883a05b5c3ab40972.png

2.4,为查询结果指定别名

select  column  [as] 别名 from 表名;

示例:

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

mysql> select id,name,math+chinese+english  ‘总分’  from exam_result;

https://i-blog.csdnimg.cn/direct/ca3e4d9da7a947bab67fa5563b4a5852.png

2.5,结果去重

math列中的数据98重复了。

https://i-blog.csdnimg.cn/direct/2953010e517f480cbab37f6fb8af50fc.png

去重,需要使用 distinct

mysql> select distinct math from exam_result;

https://i-blog.csdnimg.cn/direct/c308e0e5c57b4427bf2df023309638c7.png

2.6,where条件

前面讲的select 用法,是用来筛选出哪些列,而接下来的这部分内容where条件,是筛选出满足条件的行。

比较运算符

  • >,>=,<,<=:大于,大于等于,小于,小于等于
  • =:等于,比较null值时不安全,比如null=null返回的结果是null
  • <=>:等于,比较null值时是安全的,比如null=null返回的结果是1
  • !=,<>:不等于
  • between a0  and  a1:范围匹配,[a0,a1],如果a0<=values<=a1,返回true(1)
  • in(option…):如果是option中的任意一个,返回true(1)
  • is null:是空
  • is not null:不是空
  • like:模糊匹配。%表示任意多个字符(包括0个),_表示任意一个字符

逻辑运算符

  • and:多个条件必须都为true,结果才为true
  • or:只要有一个条件为true,结果就为true
  • not:如果条件为true(1),结果就为false(0)

null和null的比较,=和<=>的比较:

https://i-blog.csdnimg.cn/direct/6f1e88f4bd2a4f729fe0f7d9966dd46a.png

https://i-blog.csdnimg.cn/direct/ebf6ab0cba4a43f288e908f2d22ddce9.png

https://i-blog.csdnimg.cn/direct/e88f59a3e8bf4e1e918b803935985772.png

使用案例:

  • 英语成绩不及格的同学及英语成绩(<60)

mysql> select name,english from exam_result where english<60 ;

https://i-blog.csdnimg.cn/direct/5777f294e32a4fa68cf8f4d660066387.png

  • 语文成绩在[80,90]的同学及语文成绩

mysql> select name,chinese from exam_result where chinese>=80 and chinese<=90;

mysql> select name,chinese from exam_result where chinese between 80 and 90 ;

https://i-blog.csdnimg.cn/direct/95d7df3bbbc54d35be6d2f9a525a040e.png

  • 数学成绩是58或者59或者98或者99的同学及数学成绩

mysql> select name,math from exam_result where m ath=58 or math=59 or math=98 or math=99;

mysql> select name,math from exam_result where math in (58,59,98,99);

https://i-blog.csdnimg.cn/direct/24c22a3ef66345fc862c4a1ca93cfe1f.png

  • 姓孙的同学

mysql> select name from exam_result where name like ‘孙%’;

https://i-blog.csdnimg.cn/direct/7aa6991334574d86addffdb1661481ce.png

  • 孙某同学

mysql> select name from exam_result where name like ‘孙_’;

https://i-blog.csdnimg.cn/direct/05b98f6a45ad4f3b8378968456b47167.png

  • 语文成绩好于英语成绩的同学

//where条件中比较运算符两侧都是字段

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

https://i-blog.csdnimg.cn/direct/ae880699a9804b36b4f6725207ecd261.png

  • 总分在200分以下的同学

mysql> select name,math+chinese+english from exam_result where math+chinese+english<200;

https://i-blog.csdnimg.cn/direct/77de2715df974e3c8e5a7af5f1e09391.png

前面在select内容部分,我们可以为查询结果math+chinese+english取别名。但在where子句中是否可以使用别名呢?

https://i-blog.csdnimg.cn/direct/9c29bc1e1e0242368421634766eb05d0.png

可以看到是不能使用的。这和mysql的执行顺序有关。 https://i-blog.csdnimg.cn/direct/107aa50bccd44bd1b462016d51380b49.png

总结:先确定操作哪张表,再根据where子句的条件筛选出我们想要的数据,最后再显示出来。

所以在where子句中不能使用别名,但在select中仍然可以使用。

https://i-blog.csdnimg.cn/direct/770c192120374fa5b9c8318a52eb6474.png

  • 语文成绩>80并且不姓孙的同学

mysql> select name,chinese from exam_result where chinese>80 and name not like ‘孙%’;

https://i-blog.csdnimg.cn/direct/bfd6317e2b04453d8be61447065a2d9d.png

  • 孙某同学,或者总成绩>200并且语文成绩<数学成绩并且英语成绩>80

mysql> select name,chinese,math,english,chinese+math+english ‘总分’ from exam_result where name like ‘孙_’ or (chinese+math+english>200 and chinese80);

https://i-blog.csdnimg.cn/direct/22ced80b68b44b7aa620cabb1047d842.png

2.7,结果排序

语法:

—ASC 升序(从小到大)

—DESC 降序(从大到小)

—默认为ASC

select …… from table_name [where…] order by column [ASC|DESC];

注意:null视为比任何值都小

案例:

  • 查询同学及数学成绩,数学成绩按照升序显示

mysql> select name,math from exam_result order by math;

https://i-blog.csdnimg.cn/direct/3bc29eb16af44322ababd3a5c7ea748b.png

  • 查询同学各门成绩,依次按数学降序,英语升序,语文升序的方式显示

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

https://i-blog.csdnimg.cn/direct/e454123190ab47aabbb259204d17e565.png

  • 查询同学及总分, 由高到低

mysql> select name,math+chinese+english from exam_result order by chinese+math+english desc;

https://i-blog.csdnimg.cn/direct/1db7d6cd5222447ab627479fd235c891.png

order by 子句可以使用别名

mysql> select name,math+chinese+english ‘总分’ from exam_result order by 总分 desc;

https://i-blog.csdnimg.cn/direct/23801352aabb4f34bc4c319089ba65bd.png

在这里为什么可以使用别名了呢?同样这和mysql的子句执行顺序有关。

https://i-blog.csdnimg.cn/direct/0b2bfb1f037b4a65a4e5ce424f8cf5e6.png

总结:首先我们需要确定操作哪张表,如果第二步就执行排序,其实表中有一部分数据是不需要进行排序的, 这样做太浪费时间和空间了。所以先确定操作哪张表,再根据where子句条件筛选出来我们要的数据,这时的数据一定是被筛选出来的有价值的数据,这时我们只是选出来数据了,不给显示出来,最后经过排序,再将数据显示出来。

因此执行ordere by时,别名已经定义了,所以可以使用。

2.8,筛选分页结果

语法:

—-起始下标从0开始

—从0开始,筛选n条结果

select ……from table_name [where…]  [order by…] limit n;

—从s开始,筛选n条结果

select ……from table_name [where…]  [order by…] limit s,n;

—从s开始,筛选n条结果,和第二种方法表示一样

select ……from table_name [where…]  [order by…] limit n offset s;

注意:limit的执行顺序比order by还要靠后

按id进行分页,分别显示第1,2,3页

https://i-blog.csdnimg.cn/direct/095c19aa0063400e86b972b0e298bbb8.png

https://i-blog.csdnimg.cn/direct/77d52495dedf41ed8a10a7783f298a28.png

3,Update

语法:

update table_name set column=expr [column=expr…]  [where…] [order by…] [limit…]

案例:

  • 将孙悟空同学的数学成绩变更为80

mysql> update exam_result set math=80 where name=‘孙悟空’;

https://i-blog.csdnimg.cn/direct/9fe8b3a13c15490c899e89e572719a72.png

  • 将曹孟德同学的数学成绩变更为60,语文成绩变更为70

mysql> update exam_result set math=60,chinese=70 where name=‘曹孟德’;

https://i-blog.csdnimg.cn/direct/748b9431320e4d11acdf0b25fa3181ce.png

  • 将总成绩倒数前 3的同学的数学成绩加上30分

mysql> select name,math,chinese+math+english 总分 from exam_result order by 总分 limit 3;

https://i-blog.csdnimg.cn/direct/1049d87f4ca6499996cbfd9999d70a24.png

4,Delete

4.1,删除数据

语法:

delete from table_name [where…] [order by…] [limit …]

注意:如果delete from 表名,会将表的内容清空

案例:

  • 删除孙悟空同学的考试成绩

mysql> delete from exam_result where name=‘孙悟空’;

https://i-blog.csdnimg.cn/direct/12e09e571e304c9c9756157529ba15ae.png

4.2,删除整张表

  • 准备测试表

**mysql> create table for_delete(

-> id int primary key auto_increment,

-> name varchar(20));**

其中id有自增属性。

  • 插入测试数据

mysql> insert into for_delete values (1,‘A’),(2,‘B’),(3,‘C’);

  • 查看测试数据

https://i-blog.csdnimg.cn/direct/b8c8e2702f57490ebddf01daf669b892.png

  • 删除整张表 ,查看删除结果

mysql> delete from for_delete;

mysql> select * from for_delete;

https://i-blog.csdnimg.cn/direct/e3f82610b3d94a5bb99a0a4b53ccfa67.png

  • 删除表之前id自增到3,现在插入一条新数据。

mysql> insert into for_delete (name) values (‘D’);

https://i-blog.csdnimg.cn/direct/54b722680b0a4374901811e89478ec4b.png

可以发现在清空表后,id的自增值没有变为0。可以通过show查看表结构。

mysql> show create table for_delete\G

https://i-blog.csdnimg.cn/direct/eccc569518d64b73a24c67abc7e22655.png

4.3,截断表

语法:

truncate [table] table_name

注意:这个 操作慎用

1,这个操作只能对整张表使用,不能向delete一样针对部分数据操作

2,不对数据操作,所以比delete快,但是truncate 在删除数据的时候, 并不经过正真的事务,所以无法回滚

3,该操作与delete相比,它会 重置auto_increment项

案例:

  • 准备测试表(和for_delete表属性一样)

mysql> create table for_truncate like for_delete;

https://i-blog.csdnimg.cn/direct/20d76e8d4c5746b4a2315e656ce90b3d.png

  • 插入测试数据 ,查看测试数据

mysql> insert into for_truncate values (1,‘A’),(2,‘B’),(3,‘C’);

mysql> select * from for_truncate;

https://i-blog.csdnimg.cn/direct/5890f65a9f724e5ea2d7e6081396f851.png

  • 截断整表数据,注意影响行数是0,所以实际上没有对表真正操作

mysql> truncate table for_truncate;

https://i-blog.csdnimg.cn/direct/606c4ab22c2548fe8b9b4d7962dccc11.png

  • 查看删除结果

mysql> select * from for_truncate;

https://i-blog.csdnimg.cn/direct/b0b4edee1b9249ca9657a5a6e85373ff.png

  • 再插入 一条数据,自增id重新开始增长

mysql> insert into for_truncate (name) values (‘D’);

https://i-blog.csdnimg.cn/direct/3b195f3ca2084e59952d356e5ea544f8.png

  • 查看表结构

mysql> show create table for_truncate \G

https://i-blog.csdnimg.cn/direct/605b9c54bdcc4deaa559a1f8ee827db7.png

5, 插入查询结果

语法:

insert into table_name [column…]  select …

案例:删除表中的重复记录,重复数据只能有一份

  • 创建原数据表

**mysql> create table duplicate_table(

-> id int,

-> name varchar(20));**

  • 插入测试数据

mysql> insert into duplicate_table values  (100,‘aaa’), (100,‘aaa’), (200,‘bbb’), (200,‘bbb’), (200,‘bbb’), (300,‘ccc’);

思路:

  • 创建一张空表no_duplicate_table,结构和duplicate_table一样

mysql> create table no_duplicate_table like duplicate_table;

https://i-blog.csdnimg.cn/direct/0c7a84cf11e6464a8c5ff280c63f1bb3.png

  • 将 duplicate_table数据去重插入到no_duolicate_table表中

**mysql> insert into no_duplicate_table select distinct

  • from duplicate_table;**

https://i-blog.csdnimg.cn/direct/77220bae5372487b8640ca23d3af80a3.png

  • 通过重命名,做到原子的去重操作

mysql> rename table duplicate_table to old_duplicate_table;

mysql> rename table no_duplicate_table to duplicate_table;

  • 查看最终结果

https://i-blog.csdnimg.cn/direct/535e918d9d07485182283afae5863f23.png

6,聚合函数

count():返回查询到的数据的数量

sum():返回查询到的数据的总和,不是数字没有意义

avg():返回查询到的数据的平均值,不是数字没有意义

max():返回查询到的数据的最大值,不是数字没有意义

min():返回查询到的数据的最小值,不是数字没有意义

案例:

  • 统计班级共有多少学生

//使用*做统计

mysql> select count(*) from exam_result;

https://i-blog.csdnimg.cn/direct/977541a4958c4cd9962fef85c0e8113b.png

//使用表达式统计

mysql> select count(1) from exam_result;

https://i-blog.csdnimg.cn/direct/6e63e763930c48b89afdd694235eaec5.png

  • 统计数学成绩总分

mysql> select sum(math) from exam_result;

https://i-blog.csdnimg.cn/direct/0f116e143545429b91958696e435679f.png

  • 统计平均总分

mysql> select avg(chinese+math+english) 平均总分 from exam_result;

https://i-blog.csdnimg.cn/direct/0bc4cab9c0e34663995b68023094f45c.png

  • 统计数学成绩中不重复的成绩个数

mysql> select count(distinct math) 不重复的个数 from exam_result;

https://i-blog.csdnimg.cn/direct/3b27609ca93347ae96f7cd7b8886f481.png

  • 返回英语最高分

mysql> select max(english) from exam_result;

https://i-blog.csdnimg.cn/direct/459d46a0088d4ee8b2f65595f343255e.png

  • 返回>70分以上的最低分

mysql> select min(math) from exam_result where math>70;

https://i-blog.csdnimg.cn/direct/0e3455d5402b4b27b8ea8c90e10208d9.png

7,group by子句的使用

在select 中使用 group by

子句 可以对指定列进行 分组查询

select column1 column2… from table group by column

案例:

准备工作,创建一个雇员信息数据库:

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

https://i-blog.csdnimg.cn/direct/86e150ad99654b1caa9f1b730847e570.png

https://i-blog.csdnimg.cn/direct/fa3be8524faa4c4896d898a29bc7f9d8.png

  • 如何显示每个部门的平均工资和最高工资

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

https://i-blog.csdnimg.cn/direct/b38255a7b147402fa40acc19f5145d62.png

总结:

分组,可以理解为把一张表按照条件在逻辑上分成了很多子表,然后分别对各自的子表进行聚合统计。

分组聚合结果:

https://i-blog.csdnimg.cn/direct/c337dd5447584b4bb840a898dccc821f.png

  • 显示每个部门的每种岗位的 平均工资和最低工资

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

https://i-blog.csdnimg.cn/direct/32dd9db569f14681b6bf8727522176fa.png

  • 显示平均工资低于2000的部门和它的平均工资

首先统计各个部门的平均工资

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

https://i-blog.csdnimg.cn/direct/593d5ad0ccab4937b87003ffb947d7f2.png

having和group by配合使用,对group by的结果进行过滤

mysql> select deptno,avg(sal) 平均工资 from emp group by deptno having 平均工资<2000;

having经常和group by搭配使用,作用是对分组进行筛选,作用有些像where

https://i-blog.csdnimg.cn/direct/265866f2e32742be90dc7c2d8b511b35.png

结语:

最后在这里再加曾经的一道面试题:

SQL查询中各个关键字的执行顺序:from>on>join>where>group by>with>having>select>distinct>order by>limit

下篇博主会再更新一些相关的实战OJ题