MySQL基本查询

对于表内的数据,mysql提供增删查改四种操作方式,需要分别一一学习。

Create(创建)

语法:insert [into]  table_name [cloumn1,cloumn2...] values (list_value1,list_value2...]

insert:插入数据的关键字

[into]:后面跟着想插入的表

table_name: 表的名称

cloumn1..:列名

vlaues: 关键字,左边是列名,右边是插入的数据

list_value: 插入的数据。

对于插入数据来说,我们可以多行插入,也可以单行插入。 

单行数据插入

对于单行插入数据,又分为全列插入和单列插入。

我们先创建一个表,通过该表来进行演示 

全列插入

一般如果values关键字左边的列名省略,就是全列插入,需要显示的添加上所有的数据。

 如果没有省略,但是左边选上了所有的列名,这也是全列插入。

单列插入

如果values关键字左边的列名只带了部分列,那么就是单列插入,不过需要注意,所有的插入操作都要遵守表的约束才可,否则会出错。

多行数据插入

插入数据我们也可以多行插入数据,就像语法那样,在value_list 后面跟一个逗号分割即可。

全列插入

和单行数据插入一样,左边可以不选列名默认全列插入,也可以全选来全列插入。 

单列插入 

也可以在表的约束下来选择自己想插入哪几列数据。

插入否则更新

在使用mysql插入数据的过程中,总会碰到各种各样的键冲突的,有时用户不确定是否会碰到键冲突,但是这个数据又需要插入到表中,于是mysql就推出了插入否则更新的语法。

语法:insert ... on duplicate key update column=value,[colum = value...]

具体语法就是在插入数据的后面跟上on duplicate key update 关键字,然后跟上需要更新的列和名称。

 不过有一点需要注意,更新后的值也不能和其他存在的数据有冲突,否则就会出错。

此外,在更新的时候会出现这条语句:

 这条语句是有含义的。

  • 0 row affected : 表中有冲突的值,但是冲突数据和update的数据一样
  • 1 row affected: 表中没有冲突的数据,数据被插入
  • 2 row affected: 表中有冲突的数据,并且数据被更新

替换

在mysql的语法中,还有可以直接替换冲突数据的语法,我们来学习一下 

语法:replace into table_name (column1...) values (value_list1,value_list2...)

 实际上这个语法就是将insert替换成replace即可。

 

而指令输入后,返回的语句也是有含义的。

1 rows affected : 表中没有冲突数据,直接插入数据

2 rows affected: 表中有冲突数据,删除原本数据后插入。 

Retrieve(读取)

mysql中最重要的就是它的查询功能。

语法: select [distinct] { * | {column1,column2...} from table_name [where...] [order by column [ ASC | DESC...}  limit...

select : 读取关键字

distinct:表示去重

* :表示查询表中的所有数据,我们也可以表明查指定列

where子句: 给查询子句添加限定条件。

order by : 使查询的子句按一定的顺序排序

limit:给查询添加一定的限制

全列查询

全列查询很简单,采用 * 即可全列查询。

命令: select * from table_name;

 不过一般不建议采用 * 进行查询,因为 * 会将所有数据全部显示输出,而mysql又是一个网络服务,如果数据太大,会消耗很长的时间。

指定列查询

当然,我们也可以指定查询某几列,指定顺序不用跟随建表的顺序。

命令:select column1, column2, column3 from table_name;

查询字段为表达式

查询操作也可以直接查询一个表达式。

 为查询字段指定别名

我们也可以为查询的字段指定别名。

指定别名有两种方式 :

  1. 添加 as 关键字
  2. 直接在字段后面添加别名

为查询结果去重

去重操作很简单,在select后面添加distinct关键字即可。

 where子句认识

前面说过,如果一次性将表中的数据全部筛选出来,肯定是不行的,不仅耗时,而且浪费资源。

因此mysql提供了where子句供用户来进行限定。

为了方便用户使用,mysql提供了很多相关运算符供用户使用。

比较运算符:

运算符说明
>,>=,<,<=大于,大于等于,小于,小于等于
=        等于,不过不能用来比较NULL,不安全
<=>        等于,可以用来比较NULL
!=,<>不等于
between a  and b范围匹配,如果值在 [a,b],返回true
in(option...)符合 option 中的任意一个就返回 true;
is NULL       是NULL
is not NULL 不是NULL
like模糊匹配,%表示多个(或0个)字符,_ 表示任意一个字符

逻辑运算符

运算符说明
AND多个条件都是true 才是ture,相当于 &&
OR有一个为true就是true,相当于 ||
NOT条件为ture,结果为false

在上面的一系列比较运算符中,like运算符是比较难理解的,我们可以看看它的案列。

通过案列,我们可以了解到,like 运算符就像正则库一样,后面跟着 % 就说明只需要匹配 % 前面的字符,后面不管有多少字符都复合条件,而 后面跟着 _ 就说明后面只能一个字符。 

除了 like 有点抽象,其他的就如同字面意思,可以直接使用,当然不同的运算符之间当然可以结合使用。

比如查询某一成绩在80到90分之间可以采用两种方式。

其中有一个需要了解,即 where 子句后面不能使用别名。

结果排序

对于表中的数据,我们希望它能够按一定的顺序排序,如果在查询的时候没有指定,一般是按插入的顺序输出,因此我们可以给select 语句添加 order by 来限定顺序。

 一般排序默认按照 acs 排序,即升序排序,我们也可以指定按desc排序,即降序排序。

NULL 是被视为最小的数,因此升序排序时,null会在最上面。

当然,我们也可以按多个数据来排序。

比如这里,按math降序排序,english 和 chinese 按升序排序

这里一般只有当math 相等,才会按 english 排序,english 相同,再按chinese排序。

 也可以按表达式来排序。

order by 指令也可以结合之前的where子句来更近一步限定范围,然后排序。

而一般来说,order by 是可以根据别名来排序的。

 但是前面说过,where是不能根据别名来筛选的,因此我们虽然可以通过别名来排序,但是前面要注意不能用where来筛选别名。

筛选分页结果

语法:

从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 关键字一般都是在 where 以及 order by 之后才能起作用。

它的作用就是分页,防止陌生数据库一次性查询数据过多,导致数据库卡死。

接着我们直接使用一下 limit 的三种方式。

从结果来看,我们能够发现,表中的数据是从0 开始排序的,即下标从 0 开始。

通过order by 和 limit 配合查看到前三名的数据。

  通过这两个子句的配合,能够进行比较多的操作。

Update(更新)

语法:update table_name set column=expr [column=expr...] [where ...] [order by ...] [limit ...]

对查询到的值进行列值更新。 

使用update是很危险的一件事,如果你的update没有添加where关键字来进行筛选,那么数据库会默认将表中的所有数据全部更新一遍,这样的话可就难恢复了,因此使用update时一定要记住添加好筛选条件。

比如这里我更新张三的数学成绩为80,可以看到张三的数学成绩变为80了。

当然,我们也能够通过配合 order by 命令 和 limit 来指定修改哪部分的数据。

注意:mysql 不支持 += 的操作,因此这里只能 math = math + 30; 

除此之外,我们也可以同时修改多个属性。

 Delete(删除)

语法:delete from table_name [where...] [order by...] [limit...]

删除操作和update类似,如果不添加后续的子语句来限定范围,那么它的范围就是表内的所有数据。

比如如果我想删除张三的成绩,可以通过 where 来进行限定范围。

 当然我们也可以直接删除整表的数据,不过delete有一点比较特殊的点需要了解,这里我创建一个新表来测试。

这里我创建一个for_delete 表,它的 id 是自动增长的。

接着插入三个数据,根据 auto_increment  的约束,插入三个数据后,auto_increment 的值变为了3,那么我们delete后,auto_increment 会不会变为0呢?

接着使用 delete from for_delzhe后查看auto_increment 的值,发现值没有变化,就知道auto_increment没有变化了。 

 这说明delete虽然会删除整表的数据,但是auto_increment 的值不会改变。

截断表

语法:truncate [table] table_name;

而删除表的数据还有 truncate 操作。

  • 只能对整表操作
  • 由于mysql 不对数据操作,因此 truncate 比 delete 快,不过由于 truncate 在删除数据时,不经过事物,因此不能回滚
  • 会重置 auto_increment 

我们来实验一下,创建一个新表,它的id也是auto_increament 的,然后插入三个数据。

 发现 auto_increment 确实成为4了。

然后使用 truncate for_truncate 来删除整表。

发现auto_increment 的值不见了,再插入一个数据后,发现值确实从1开始增长。

在介绍 truncate 的时候,曾了解到 truncate 的速度比 delete 快,这和mysql 中的事物概念有关,这点后面再说,不过由于 truncate 不经过事物,它的操作也不会保存在 mysql 的日志中,因此用户也无法通过日志来恢复被 truncate 删除的数据,因此 turncate 删除操作无法回滚。

bin log:mysql下的二进制日志,记录了所有 DDL 语句和DML语句,但不包括数据查询语句

当出现灾难时,可以用 bin log 进行数据恢复。

去重表操作

 我们可以通过insert 和 select 两个指令来进行去重操作。

我们先创建一个表。

然后向表中插入重复的数据。

 

接着我们创建另一个表,它的数据结构和 duplicate 一样。

通过 insert into no_duplicate select distinct * from duplicate; 来实现去重插入操作。

通过distinct进行去重选择,然后将选择到的数据全部插入到no_duplicate;

最后我们将 no_duplicate 重命名即可。

先将 duplicate 修改名字,再修改 no_duplicate 为 duplicate;

至于为何采用 rename 的原因就是 rename 的操作是原子型的,可以回避各种错误。

就像我们上传文件,操作系统都是先接收一个临时文件夹,接收完后再直接将数据 move 到文件夹中,这样可以避免外部写入操作或者读取操作出现错误。 

聚合函数

函数名说明
count([distinct expr])返回查询到的数据的数量
sum([distinct expr])返回查询到的数据总量,不是数字没意义
avg([distinct expr])返回查询到的数据平均值,不是数字没意义
max([distinct expr])返回查询到的数据最大值,不是数字没意义
min([distinct expr]) 返回到查询到的数据最小值,不是数字没意义

这些聚合函数是用来查询表中对应的数据,比如数据的总值,数据的最大值之类的,它们只能对整型变量起作用。

比如这里,可以采用 select count(*) from t1; 来查看表中一共有多少条数据。

不过有意思的是,select count(1) from t1 也能输出总数,只不过名称变成了 count(1);这是因为count 是从 t1 中读取数据的条数,t1有多少条就输出多少条,而跟名称其实没什么关系,只有后面添加了限定语句才能够出现不同。

当然我们可以同时调用多个聚合语句。

 

 不过聚合语句是不能对数字以外的数据起作用的。

对名字求和直接返回0,因为不是数字,而且如果在聚合语句前面查询非数字的数据,就会出现报错,这就需要分组的帮助了。

分组聚合

语法:select .... from table [where...] group by expr;

在select 语句后面添加group by语句可以按照expr来将数据进行分组

然后可以将这些分组的数据进行聚合。

 我先将学生分到三个班级中。

分别找到三个班级中数学的最高分

通过 select class_id(math) from student group by class_id; 即可找到三个班中最高的数学成绩。

 实际上group by 语句就是将一整个表按列的数据分成多个分表。

比如这里的总表是 student,通过group by 语句按 class_id 将表分成三个表,然后再通过聚合语句来分别找到数学最高分。

也就是说分组聚合的顺序是先分组,再聚合

如果还想看到数学成绩最高分的拥有者是谁,是否可以直接添加一个 select name 呢?

我们发现是不可以的,因为出现了聚合语句,那么select后面的列名必须在group by 后面出现过。

但是这样我们发现获取的直接就是所有数据了,这是因为group by 不仅按class_id进行分表,还按name进行了分表,而name都不相同,因此就分出了n个表,正好是所有数据。

而如果我们只需要1班和2班的最高数学成绩而不要3班的,我们可以这样写。

 

语法: 在group by 后面添加 having 语句。

having  的作用和where 类似,不过不同的是,where是对任意列直接进行具体的筛选,而having 是对分组后的数据进行筛选。

having 经常和 group by 组合。

总结

以上就是mysql对表中数据的增删查改等语句的操作,以及聚合函数和分组聚合,希望对大家有所帮助。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值