MySQL 进阶查询
- 常用查询
- 按关键字排序
- 对结果进行分组
- 限制结果条目
- 设置别名
- 通配符
- 子查询
- Null 值
- 正则表达式
- 以特定字符串开头的记录
- 运算符
- 支持使用的算术运算符:
- 支持使用的比较运算符
- 逻辑运算符
- 逻辑非
- 逻辑与
- 逻辑或
- 逻辑异或
- 位运算符
- 运算符的优先级
- 数据库函数
- 聚合函数
- 字符串函数
- 日期时间函数
常用查询
按关键字排序
使用SELECT语句可以将需要的数据从MySQL数据库中查询出来,如果对查询的结果进行排序,该如何去实现呢?
可以使用 ORDER BY 语句来完成排序,并最终将排序后的结果返回给用户。这个语句的排序不光可以针对某一个字段,也可以针对多个字段。以下就是MySQL中ORDER BY语句的语法结构
###语法结构###
SELECT column1, column2, .. FROM table_name ORDER BY column1, column2,.. ASC|DESC;
排序的字段可以根据具体需求进行选择,没有限制。排序的关键字可以使用 ASC 或者DESC。ASC 是按照升序进行排序的,
是默认的排序方式,即 ASC 可以省略。SELECT 语句中如果没有指定具体的排序方式,则默认按 ASC 方式进行排序。
DESC 是按降序方式进行排列。当然 ORDER BY 前面也可以使用 WHERE 子句对查询结果进一步过滤。
##搭建环境
[root@localhost ~]# mysql -uroot -pabc123
mysql> create database player;
ERROR 1007 (HY000): Can't create database 'player'; database exists
mysql> drop database player;
Query OK, 1 row affected (0.00 sec)
mysql> create database player;
Query OK, 1 row affected (0.00 sec)
mysql> use player;
Database changed
mysql> create table player (id int(4) not null,name varchar(10) not null,level int(3) not null,primary key (`id`));
Query OK, 0 rows affected (0.01 sec)
mysql> insert into player (id,name,level) values ('30','抢宝真多呀',47);
Query OK, 1 row affected (0.03 sec)
mysql> insert into player (id,name,level) values ('15','新五皇·白胡子',46);
Query OK, 1 row affected (0.00 sec)
mysql> insert into player (id,name,level) values ('63','新五皇–敬神',46);
Query OK, 1 row affected (0.00 sec)
mysql> insert into player (id,name,level) values ('199','D 丶狙击王',46);
Query OK, 1 row affected (0.01 sec)
mysql> insert into player (id,name,level) values ('298','唐三',46);
Query OK, 1 row affected (0.00 sec)
mysql> insert into player (id,name,level) values ('51','新五皇·暴雪',45);
Query OK, 1 row affected (0.00 sec)
mysql> insert into player (id,name,level) values ('272','D 丶抢人头辅助',45);
Query OK, 1 row affected (0.00 sec)
mysql> select * from player;
+-----+----------------------+-------+
| id | name | level |
+-----+----------------------+-------+
| 15 | 新五皇·白胡子 | 46 |
| 30 | 抢宝真多呀 | 47 |
| 51 | 新五皇·暴雪 | 45 |
| 63 | 新五皇–敬神 | 46 |
| 199 | D 丶狙击王 | 46 |
| 272 | D 丶抢人头辅助 | 45 |
| 298 | 唐三 | 46 |
+-----+----------------------+-------+
7 rows in set (0.00 sec)
###查询player中id,name,level的数据,并且按照level降序排序显示
mysql> select id,name,level from player where level>=45 order by level desc;
+-----+----------------------+-------+
| id | name | level |
+-----+----------------------+-------+
| 30 | 抢宝真多呀 | 47 |
| 15 | 新五皇·白胡子 | 46 |
| 63 | 新五皇–敬神 | 46 |
| 199 | D 丶狙击王 | 46 |
| 298 | 唐三 | 46 |
| 51 | 新五皇·暴雪 | 45 |
| 272 | D 丶抢人头辅助 | 45 |
+-----+----------------------+-------+
7 rows in set (0.00 sec)
ORDER BY 语句也可以使用多个字段来进行排序,当排序的第一个字段相同的记录有多条的情况下,这些多条的记录再按 照第二个字段进行排序
##查询player表中等级在 45 级及以上的用户,并以 level 降序排列和 id 降序排列
mysql> select id,name,level from player where level>=45 order by level desc,id desc;
+-----+----------------------+-------+
| id | name | level |
+-----+----------------------+-------+
| 30 | 抢宝真多呀 | 47 |
| 298 | 唐三 | 46 |
| 199 | D 丶狙击王 | 46 |
| 63 | 新五皇–敬神 | 46 |
| 15 | 新五皇·白胡子 | 46 |
| 272 | D 丶抢人头辅助 | 45 |
| 51 | 新五皇·暴雪 | 45 |
+-----+----------------------+-------+
7 rows in set (0.01 sec)
# 先执行有id,name.levle的数据,再执行等级45大于等于45再执行等级降序,最后执行id降序,按顺序执行命令
# ORDER BY 后面跟多个字段时,字段之间使用英文逗号隔开,
# 优先级是按先后顺序而定。下面以A和B分别表示两个字段。
# ORDER BY A,B desc 指A用升序,B用降序;
# ORDER BY A asc,B desc 指A用升序,B用降序;
# ORDER BY A desc,B desc 指A用降序,B用降序;
对结果进行分组
通过 SQL 查询出来的结果,还可以对其进行分组,使用 GROUP BY 语句来实现。
GROUP BY 从字面上看,是以 BY 后面的内容对查询出的数据进行分组,就是将一个“数据集”划分成若干个“小区域”,然后针对这些个“小区域”进行数据处理。
GROUP BY通常都是结合聚合函数一起使用的,常用的聚合函数包括:
计数(COUNT)、求和(SUM)、求平均数(AVG)、最大值(MAX)、最小值(MIN)
GROUP BY 分组的时候可以按一个或多个字段对结果进行分组处理
语法结构: |
SELECT column_name, aggregate_function(column_name)FROM table_name WHERE column_name operator valueGROUP BY column_name; |
GROUP BY除了配合聚合函数一起使用外,还可以引入WHERE子句。首先通过WHERE过滤掉一部分不符合需求的查询结果,然后再对结果进行分组。如果有排序的需求, 也可以引入ORDER BY语句
#统计等级在 45 级及以上,以等级为分组,每个等级有多少人
mysql> select count(name),level from player where level>=45 group by level;
+-------------+-------+
| count(name) | level |
+-------------+-------+
| 2 | 45 |
| 4 | 46 |
| 1 | 47 |
+-------------+-------+
从以上结果可以看出,每个等级的人数已经统计出来了,但是数量是无序的。如果结果条目变得更多,很难一眼看出哪个等级的人数是最多的,所以需要对数量进行排序。而GROUP BY 结合 ORDER BY 即可实现分组并排序的查询
##查询等级在45级及以上, 按等级进行分组,并将每个等级的人数按降序排序
mysql> select count(name),level from player where level>=45 group by level order by count(name) desc;
+-------------+-------+
| count(name) | level |
+-------------+-------+
| 4 | 46 |
| 2 | 45 |
| 1 | 47 |
+-------------+-------+
3 rows in set (0.00 sec)
限制结果条目
在使用 MySQL SELECT 语句进行查询时,结果集返回的是所有匹配的记录。有时候仅需要返回第一行或者前几行,这时候就需要用到 LIMIT 子句
语法结构 |
SELECT column1, column2, … FROM table_name LIMIT [offset,] number |
LIMIT 的第一个参数是位置偏移量(可选参数),是设置 MySQL 从哪一行开始显示
如果不设定第一个参数,将会从表中的第一条记录开始显示。需要注意的是,第一条记录的位置偏移量是 0,第二条是 1,以此类推。第二个参数是设置返回记录行的最大数目。
如果 SELECT 查询出的结果记录比较多,用户查看不是很方便。这个时候可以返回固定的、有限的记录数量,使用 MySQL 数据库的 LIMIT 子句即可实现。LIMIT 子句是一种简单的分页方法,它的使用减少了数据结果的返回时间,提高了执行效率,也解决了由于数据量过大从而导致的性能问题。
####环境创建###如果表已经创建,可以向表内插入明细数据
create table player (
-> id int(4) not null ,
-> name varchar(10) not null,
-> level int(3) not null,
-> primary key (`id`));
insert into player (id,name,level) values ('1','修欧拉卡',10);
insert into player (id,name,level) values ('2','起风了',10);
insert into player (id,name,level) values ('3','吊打低V',15);
insert into player (id,name,level) values ('4','小花',14);
insert into player (id,name,level) values ('5','小舞',35);
#查询表的前 3 个用户的信息
mysql> select id,name,level from player limit 3;
+----+--------------+-------+
| id | name | level |
+----+--------------+-------+
| 1 | 修欧拉卡 | 10 |
| 2 | 起风了 | 10 |
| 3 | 吊打低V | 15 |
+----+--------------+-------+
3 rows in set (0.00 sec)
##将查询记录按等级 level 降序排列,只取前三条记录
mysql> select id,name,level from player order by level desc limit 3;
+----+----------------------+-------+
| id | name | level |
+----+----------------------+-------+
| 30 | 抢宝真多呀 | 47 |
| 15 | 新五皇·白胡子 | 46 |
| 63 | 新五皇–敬神 | 46 |
+----+----------------------+-------+
3 rows in set (0.00 sec)
#从第 3 条记录开始显示之后的 3 条数据
mysql> select id,name,level from player limit 2,3;
+----+------------+-------+
| id | name | level |
+----+------------+-------+
| 3 | 吊打低V | 15 |
| 4 | 小花 | 14 |
| 5 | 小舞 | 35 |
+----+------------+-------+
3 rows in set (0.00 sec)
设置别名
在MySQL查询时,当表的名字比较长或者表内某些字段比较长时,为了方便书写或者多次使用相同的表,可以给字段列或表设置别名。使用的时候直接使用别名,简洁明了,增强可读性。设置别名使用AS语句
语法结构 |
SELECT column_name AS alias_name FROM table_name; |
表的别名语法结构: |
SELECT column_name(s) FROM table_name AS alias_name; |
在使用 AS 后,可以用 alias_name 代替 table_name,其中 AS 语句是可选的。AS之后的别名,主要是为表内的列或者表提供临时的名称,在查询过程中使用,库内实际的表名或字段名是不会被改变的
#在统计表内所有记录共有多少条时,使用 count(*), 这么写不便于识别,可以将其别名设置为 number
mysql> select count(*) as number from player;
+--------+
| number |
+--------+
| 12 |
+--------+
1 row in set (0.00 sec)
mysql> select count(*) as 数字 from player;
+--------+
| 数字 |
+--------+
| 12 |
+--------+
1 row in set (0.00 sec)
#表明过长敲着费劲怎么办
#将 player 表的别名设置成 p
mysql> select p.id,p.name from player as p limit 2;
+----+--------------+
| id | name |
+----+--------------+
| 1 | 修欧拉卡 |
| 2 | 起风了 |
+----+--------------+
2 rows in set (0.00 sec)
此外,AS还可以作为连接语句的操作符
#用一条 SQL语句完成在创建表tmp的时候将player表内的数据写入 tmp 表
mysql> create table tmp as select * from player;
Query OK, 12 rows affected (0.02 sec)
Records: 12 Duplicates: 0 Warnings: 0
mysql> select count(*) from tmp;
+----------+
| count(*) |
+----------+
| 12 |
+----------+
1 row in set (0.00 sec)
mysql> select * from tmp;
+-----+----------------------+-------+
| id | name | level |
+-----+----------------------+-------+
| 1 | 修欧拉卡 | 10 |
| 2 | 起风了 | 10 |
| 3 | 吊打低V | 15 |
| 4 | 小花 | 14 |
| 5 | 小舞 | 35 |
| 15 | 新五皇·白胡子 | 46 |
| 30 | 抢宝真多呀 | 47 |
| 51 | 新五皇·暴雪 | 45 |
| 63 | 新五皇–敬神 | 46 |
| 199 | D 丶狙击王 | 46 |
| 272 | D 丶抢人头辅助 | 45 |
| 298 | 唐三 | 46 |
+-----+----------------------+-------+
12 rows in set (0.00 sec)
通配符
通配符主要用于替换字符串中的部分字符,通过部分字符的匹配将相关结果查询出来。
通常通配符都是跟 LIKE 一起使用的,并协同 WHERE 子句共同来完成查询任务。
常用的通配符有两个,分别是:
% | 百分号表示零个、一个或多个字符 |
_ | 下划线表示单个字符 |
###搭建环境 有这个表直接插入数据就可以
create table player (
-> id int(4) not null ,
-> name varchar(10) not null,
-> level int(3) not null,
-> primary key (`id`));
insert into player (id,name,level) values ('238','sagou 轰总',7);
insert into player (id,name,level) values ('795','senoku',15);
insert into player (id,name,level) values ('2460','shirley',1);
insert into player (id,name,level) values ('448','useless',1);
insert into player (id,name,level) values ('713','guess',25);
insert into player (id,name,level) values ('1979','Theshy',24);
insert into player (id,name,level) values ('2237','leslieF',3);
insert into player (id,name,level) values ('1735','oooooo',1);
insert into player (id,name,level) values ('2718','ooo',1);
#查询id,name,level,要求name 以s开头
mysql> select id,name,level from player where name like 's%'
-> ;
+------+--------------+-------+
| id | name | level |
+------+--------------+-------+
| 238 | sagou 轰总 | 7 |
| 795 | senoku | 15 |
| 2460 | shirley | 1 |
+------+--------------+-------+
3 rows in set (0.00 sec)
##以s结尾
mysql> select id,name,level from player where name like '%s'
-> ;
+-----+---------+-------+
| id | name | level |
+-----+---------+-------+
| 448 | useless | 1 |
| 713 | guess | 25 |
+-----+---------+-------+
2 rows in set (0.00 sec)
#name 字段中间含 es 的记录
mysql> select id,name,level from player where name like '%es%';
+------+---------+-------+
| id | name | level |
+------+---------+-------+
| 448 | useless | 1 |
| 713 | guess | 25 |
| 1979 | Theshy | 24 |
| 2237 | leslieF | 3 |
+------+---------+-------+
4 rows in set (0.00 sec)
如果匹配name字段中某一个字符,可以使用%。但是MySQL提供的专门针对单个字符的通配符,就是“_”一个下划线,使用单个下划线可以替换字符串中的某个单字符
如果单词想不起来,mysql数据库又卡不能全查怎么办啊? |
###替换开头的一个字符
mysql> select id,name,level from player where name like '_uess';
+-----+-------+-------+
| id | name | level |
+-----+-------+-------+
| 713 | guess | 25 |
+-----+-------+-------+
1 row in set (0.00 sec)
###替换结尾的四个字符
mysql> select id,name,level from player where name like 'use____';
+-----+---------+-------+
| id | name | level |
+-----+---------+-------+
| 448 | useless | 1 |
+-----+---------+-------+
1 row in set (0.00 sec)
###替换中间的一个字
mysql> select id,name,level from player where name like 'shi_ley';
+------+---------+-------+
| id | name | level |
+------+---------+-------+
| 2460 | shirley | 1 |
+------+---------+-------+
1 row in set (0.00 sec)
实在想不起来单词长什么样子,又不知道是几位的咋办?来来你往下看 |
mysql> select id,name,level from player where name like '_es%';
+------+---------+-------+
| id | name | level |
+------+---------+-------+
| 2237 | leslieF | 3 |
+------+---------+-------+
1 row in set (0.00 sec)
子查询
子查询也被称作内查询或者嵌套查询,是指在一个查询语句里面还嵌套着另一个查询语句子查询语句是先于主查询语句被执行的
其结果作为外层的条件返回给主查询进行下一步的查询过滤。子查询不仅可以在 SELECT 语句中使用,在 INERT、UPDATE、DELETE中也同样适用。
在嵌套的时候,子查询内部还可以再次嵌套新的子查询,也就是说可以多层嵌套。在开始实际的举例之前,先来学习一下IN 这个操作符的用法,IN用来判断某个值是否在给定的结果集中,通常结合子查询来使用
IN 的语法结构 |
<表达式> [NOT] IN <子查询> |
当表达式与子查询返回的结果集中的某个值相等时,返回TRUE,否则返回 FALSE。若启用了 NOT 关键字,
则返回值相反。需要注意的是,子查询只能返回一列数据,如果需求比较复杂,一列解决不了问题
可以使用多层嵌套的方式来应对。
多数情况下,子查询都是与SELECT语句一起使用的
##先查出等级大于等于45级的 ID,然后在判断player表内的ID是不是在这个结果集内,
如果在就打印此行的名字和等级
mysql> mysql> select name,level from player where id in (select id from player where level>=45);
+----------------------+-------+
| name | level |
+----------------------+-------+
| 新五皇·白胡子 | 46 |
| 抢宝真多呀 | 47 |
| 新五皇·暴雪 | 45 |
| 新五皇–敬神 | 46 |
| D 丶狙击王 | 46 |
| D 丶抢人头辅助 | 45 |
| 唐三 | 46 |
+----------------------+-------+
7 rows in set (0.00 sec)
子查询还可以用在 INSERT 语句中。子查询的结果集可以通过 INSERT 语句插入到其他的表中。
#先清空之前使用的 tmp 表,然后通过子查询的方式将 player 的内容插入到 tmp 表中
##清空tmp表
mysql> truncate table tmp;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tmp;
Empty set (0.00 sec)
####将player表的内容插入tmp 表
mysql> insert into tmp select * from player where id in (select id from player);
Query OK, 19 rows affected (0.00 sec)
Records: 19 Duplicates: 0 Warnings: 0
UPDATE语句也可以使用子查询。UPDATE内的子查询,在set更新内容时,可以是单独的一列,也可以是多列
#通过子查询实现将等级大于等于 47 的用户减去 7
##先查看ID为30的数据情况,等级为47
mysql> select * from tmp where id=30;
+----+-----------------+-------+
| id | name | level |
+----+-----------------+-------+
| 30 | 抢宝真多呀 | 47 |
+----+-----------------+-------+
1 row in set (0.00 sec)
#类似 select 方式的子查询,MySQL 不支持,需要多引入一层子查询
mysql> update tmp set level = level - 7 where id in (select id from tmp where level >= 47);
ERROR 1093 (HY000): You can't specify target table 'tmp' for update in FROM clause
mysql> update tmp set level = level - 7 where id in (select a.id from (select id from tmp where level >= 47) a);
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select id,name,level from tmp where id=30;
+----+-----------------+-------+
| id | name | level |
+----+-----------------+-------+
| 30 | 抢宝真多呀 | 40 | ###可以看到等级已经少了 7 级
+----+-----------------+-------+
1 row in set (0.00 sec)
#再用个更简单的 改成47
mysql> update tmp set level=47 where id=30;
DELETE也适用于子查询
mysql> delete from tmp where id in (select a.id from (select id from tmp where level=47) a);
Query OK, 1 row affected (0.01 sec)
###等级为 47 的用户已经被删除
mysql>select id,name,level from tmp where id=30;
Empty set (0.00 sec)
除了以上所列举的 IN 操作符,在IN前面还可以添加NOT,其作用与IN相反,表示否定(即不在子查询的结果集里面)
#查询用户等级不小于 45 级的用户
mysql> mysql> select name,level from tmp where id not in (select id from tmp where level < 45);
+----------------------+-------+
| name | level |
+----------------------+-------+
| D 丶狙击王 | 46 |
| D 丶抢人头辅助 | 45 |
| 唐三 | 46 |
| 新五皇·白胡子 | 46 |
| 新五皇·暴雪 | 45 |
| 新五皇–敬神 | 46 |
+----------------------+-------+
6 rows in set (0.00 sec)
子查询上也可以使用比较运算符(=、<、>、>=、<=),这些运算符主要是对运算符前面的表达式和后面的子查询进行比较运算
#查询出名字是 shirley 的记录,并输出其 ID、名字和等级信息
mysql> select id,name,level from tmp where id = (select id from tmp where name='shirley');
+------+---------+-------+
| id | name | level |
+------+---------+-------+
| 2460 | shirley | 1 |
+------+---------+-------+
1 row in set (0.00 sec)
EXIST 这个关键字在子查询时,主要用于判断子查询的结果集是否为空。如果不为空, 则返回 TRUE;反之,则返回FALSE
#先通过子查询判断返回是否为TRUE,如果用户shirley存在,则计算整个tmp表的总记录数量
mysql> select count(*) as number from tmp where EXISTS (select id from tmp where name='shirley');
+--------+
| number |
+--------+
| 18 |
+--------+
1 row in set (0.00 sec)
Null 值
在SQL语句使用过程中,经常会碰到NULL这几个字符。通常使用NULL来表示缺失的值,也就是在表中该字段是没有值的。如果在创建表时,限制某些字段不为空,则可以使用NOT NULL关键字,不使用则默认可以为空。
在向表内插入记录或者更新记录时,如果该字段没有NOT NULL并且没有值,这时候新记录的该字段将被保存为 NULL。需要注意的是,NULL 值与数字 0 或者空白(spaces)的字段是不同的,值为NULL的字段是没有值的。在SQL语句中,使用IS NULL可以判断表内的某个字段是不是NULL值,相反的用IS NOT NULL 可以判断不是NULL值。
#创建一个表test,该表包含不设置NOT NULL的字段,然后向表中插入不同的记录值,其中包括NULL值和实际有
#值的记录,最后通过 SELECT 查询字段中包括 NULL 和不包括 NULL 的记录值
mysql>drop table test;
Query OK, 0 rows affected (0.01 sec)
mysql>CREATE TABLE `test` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`NAME` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`level` int(10) NOT NULL,
`coin` int(32),
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#插入的记录中不包括 coin 字段
mysql> insert into test(name,level) values('aa',10);
#插入的记录中包括 coin 字段
mysql>insert into test(name,level,coin) values('ab',20,100);
#查询 coin 字段为空值的记录
mysql>select * from test where coin is null
+----+------+-------+------+
| id | NAME | level | coin |
+----+------+-------+------+
| 1 | aa | 10 | NULL |
+----+------+-------+------+
1 row in set (0.00 sec)
#查询coin 字段不为空的记录
mysql> select * from test where coin is not null;
+----+------+-------+------+
| id | NAME | level | coin |
+----+------+-------+------+
| 2 | ab | 20 | 100 |
+----+------+-------+------+
1 row in set (0.00 sec)
提到 NULL 值就不得不说下空值,空值就是在表的字段中存储空字符(‘’),那么 NULL |
值和空值有什么区别呢?二者的区别如下: |
空值的长度为 0,不占用空间的;而NULL值的长度是 NULL,是占用空间的 |
IS NULL 或者 IS NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是空值的 |
空值的判断使用=’’或者<>’’来处理 |
在通过 count()计算有多少记录数时,如果遇到 NULL 值会自动忽略掉,遇到空值会加入到记录中进行计算 |
正则表达式
MySQL 正则表达式通常是在检索数据库记录的时候,根据指定的匹配模式匹配记录中符合要求的特殊字符串。
MySQL 的正则表达式使用 REGEXP 这个关键字来指定正则表达式的匹配模式,REGEXP 操作符所支持的匹配模式
匹配模式 | 描述 | 实例 |
^ | 匹配文本的开始字符 | ^bd’ 匹配以 bd 开头的字符串 |
$ | 匹配文本的结束字符 | ‘qn$’ 匹配以 qn 结尾的字符串 |
. | 匹配任何单个字符 | ‘s.t’ 匹配任何s 和t 之间有一个字符的字符串 |
* | 匹配零个或多个在它前面的字符 | ‘fo*t’ 匹配 t 前面有任意个 o |
+ | 匹配前面的字符 1 次或多次 | ‘hom+’ 匹配以 ho 开头,后面至少一个 |
m 的字符串 | 匹配包含指定的字符串 | ‘clo’ 匹配含有 clo 的字符串 |
p1Ip2 | 匹配 p1 或 p2 | ‘bg |
[…] | 匹配字符集合中的任意一个字符 | ‘[abc]’ 匹配 a 或者 b 或者 c |
[^…] | 匹配不在括号中的任何字符 | ‘[^ab]’ 匹配不包含 a 或者 b 的字符串 |
{n} | 匹配前面的字符串 n 次 | g{2}’ 匹配含有 2 个 g 的字符串 |
{n,m} | 匹配前面的字符串至少 n 次,至多m 次 | f{1,3}’ 匹配 f 最少 1 次,最多 3 次 |
以特定字符串开头的记录
#在player表中查询以us开头的name字段并打印对应的id、name 和 level 记录
mysql> select id,name,level from player where name REGEXP '^us';
+-----+---------+-------+
| id | name | level |
+-----+---------+-------+
| 448 | useless | 1 |
+-----+---------+-------+
1 row in set (0.00 sec)
#查询名字以ss结尾的,输出id,name,level
mysql> select id,name,level from player where name REGEXP 'ss$';
+-----+---------+-------+
| id | name | level |
+-----+---------+-------+
| 448 | useless | 1 |
| 713 | guess | 25 |
+-----+---------+-------+
2 rows in set (0.00 sec)
#查询名字中包含ok的,输出id,name,level
mysql> select id,name,level from player where name regexp 'ok';
+-----+--------+-------+
| id | name | level |
+-----+--------+-------+
| 795 | senoku | 15 |
+-----+--------+-------+
1 row in set (0.00 sec)
#在player表中查询包含字符串shir 与 ey,且两个字符串之间只有一个字符的name字段并打印对应的 id、name 和 level 记录
mysql> select id,name,level from player where name regexp 'shir.ey';
+------+---------+-------+
| id | name | level |
+------+---------+-------+
| 2460 | shirley | 1 |
+------+---------+-------+
1 row in set (0.00 sec)
#在 player 表中查询包含字符串ok或者ss的name字段并打印对应的 id、name和 level 记录
mysql> select id,name,level from player where name regexp 'ok|ss';
+-----+---------+-------+
| id | name | level |
+-----+---------+-------+
| 448 | useless | 1 |
| 713 | guess | 25 |
| 795 | senoku | 15 |
+-----+---------+-------+
3 rows in set (0.00 sec)
#在 player 表中查询包含三个或者更多个连续的 o 的 name 字段并打印对应的 id、name和level
mysql> select id,name,level from player where name regexp 'oooo*';
+------+--------+-------+
| id | name | level |
+------+--------+-------+
| 1735 | oooooo | 1 |
| 2718 | ooo | 1 |
+------+--------+-------+
2 rows in set (0.00 sec)
#在player表中查询包含四个或者更多个o的 name 字段并打印对应的 id、name和level
mysql> select id,name,level from player where name REGEXP 'oooo+';
+------+--------+-------+
| id | name | level |
+------+--------+-------+
| 1735 | oooooo | 1 |
+------+--------+-------+
1 row in set (0.00 sec)
#player表中查询包含以 d、e、f 开头的 name 字段并打印对应的 id、name 和level
mysql> select id,name,level from player where name REGEXP '^[d-f]';
+-----+----------------------+-------+
| id | name | level |
+-----+----------------------+-------+
| 199 | D 丶狙击王 | 46 |
| 272 | D 丶抢人头辅助 | 45 |
+-----+----------------------+-------+
2 rows in set (0.00 sec)
运算符
MySQL 的运算符用于对记录中的字段值进行运算。MySQL 的运算符共有四种,
分别是:算术运算符、比较运算符、逻辑运算符和位运算符
支持使用的算术运算符:
运算符 | 描述 |
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
% | 取余数 |
mysql> select 1+2 as addition, 2-1 as subtraction, 2*3 as multiplication, 4/2 as division, 7%2 as remainder;
+----------+-------------+----------------+----------+-----------+
| addition | subtraction | multiplication | division | remainder |
+----------+-------------+----------------+----------+-----------+
| 3 | 1 | 6 | 2.0000 | 1 |
+----------+-------------+----------------+----------+-----------+
1 row in set (0.00 sec)
同时我们可以直接把结果生成到表当中,比如:
mysql> select 2+2,2-1,7/2,7%2;
+-----+-----+--------+------+
| 2+2 | 2-1 | 7/2 | 7%2 |
+-----+-----+--------+------+
| 4 | 1 | 3.5000 | 1 |
+-----+-----+--------+------+
1 row in set (0.00 sec)
mysql> create table test as select 2+2,2-1,7/2,7%2;
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from test;
+-----+-----+--------+------+
| 2+2 | 2-1 | 7/2 | 7%2 |
+-----+-----+--------+------+
| 4 | 1 | 3.5000 | 1 |
+-----+-----+--------+------+
1 row in set (0.00 sec)
mysql> desc test;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| 2+2 | int(3) | NO | | 0 | |
| 2-1 | int(3) | NO | | 0 | |
| 7/2 | decimal(5,4) | YES | | NULL | |
| 7%2 | int(1) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
支持使用的比较运算符
运算符 | 描述 | 运算符 | 描述 |
= | 等于 | IS NOT NULL | 判断一个值是否不为 NULL |
> | 大于 | BETWEEN AND | 两者之间 |
< | 小于 | IN | 在集合中 |
>= | 大于等于 | LIKE | 通配符匹配 |
<= | 小于等于 | GREATEST | 两个或多个参数时返回最大值 |
!=或<> | 不等于 | LEAST | 两个或多个参数时返回最小值 |
IS NULL | 判断一个值是否为 NULL | regexp | 正则表达式 |
mysql> select 1=2;
+-----+
| 1=2 |
+-----+
| 0 |
+-----+
1 row in set (0.00 sec)
mysql> select 2=2;
+-----+
| 2=2 |
+-----+
| 1 |
+-----+
1 row in set (0.00 sec
mysql> select 2='2';
+-------+
| 2='2' |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)
##由以上结果可以看到数据库中,条件成立输出1,不成立输出0
#同时,数字加‘’后,比较的仍是数字大小
#不等于比较
mysql> select 1!=2;
+------+
| 1!=2 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select 1<>2;
+------+
| 1<>2 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
#注意,如果进行字母比较,则比较的是ASCII码表,可以到百度查询
mysql> select 'a' > 'b';
+-----------+
| 'a' > 'b' |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)
#因为a在表中是97,b是98,所以a比b大不成立
#比较运算符和数字运算符还可同时使用
mysql> select (1+1)=(3-1);
+-------------+
| (1+1)=(3-1) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
#需要注意的是null,如果比较中有一个是null,则比较的结果就是null
mysql> select 'a' = null;
+------------+
| 'a' = null |
+------------+
| NULL |
+------------+
1 row in set (0.00 sec)
mysql> select 2 = null;
+----------+
| 2 = null |
+----------+
| NULL |
+----------+
1 row in set (0.00 sec)
mysql> select 2 != null;
+-----------+
| 2 != null |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
#如果两个字符串相比较
mysql> select 'abc'='abc';
+-------------+
| 'abc'='abc' |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select 'abc'='cba';
+-------------+
| 'abc'='cba' |
+-------------+
| 0 |
+-------------+
1 row in set (0.00 sec)
##总结:等于比较的是内容中的不仅是个数,还有前后顺序##
mysql> select 'abc' > 'bac';
+---------------+
| 'abc' > 'bac' |
+---------------+
| 0 |
+---------------+
1 row in set (0.00 sec)
mysql> select 'abc' < 'bac';
+---------------+
| 'abc' < 'bac' |
+---------------+
| 1 |
+---------------+
1 row in set (0.01 sec)
mysql> select 'acb' > 'abc';
+---------------+
| 'acb' > 'abc' |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)
##总结:通过ASCII码表 从左往右一个一个比较,只要有一个成立既成立
##所以,字符串比较是或的关系
#IS NULL、IS NOT NULL的用法
#IS NULL 判断一个值是否为 NULL,如果为 NULL 返回 1,否则返回 0。
#IS NOT NULL 判断一个值是否不为 NULL,如果不为 NULL 返回 1,否则返回 0
mysql> select 2 is null,'a' is not null,null is null,null is not null;
+-----------+-----------------+--------------+------------------+
| 2 is null | 'a' is not null | null is null | null is not null |
+-----------+-----------------+--------------+------------------+
| 0 | 1 | 1 | 0 |
+-----------+-----------------+--------------+------------------+
1 row in set (0.00 sec)
#BETWEEN AND用法
#BETWEEN AND 比较运算通常用于判断一个值是否落在某两个值之间,包含两个值本身
mysql> select 4 between 2 and 6;
+-------------------+
| 4 between 2 and 6 |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
mysql> select 2 between 2 and 6;
+-------------------+
| 2 between 2 and 6 |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
mysql> select 6 between 2 and 6;
+-------------------+
| 6 between 2 and 6 |
+-------------------+
| 1 |
+-------------------+
1 row in set (0.00 sec)
#总结:between and比较,包含两个值本身
#LEAST、GREATEST用法
#LEAST:当有两个或者多个参数时,返回其中的最小值。如果其中一个值为 NULL,则返回结果就为 NULL。
#GREATEST:当有两个或者多个参数时,返回其中的最大值。如果其中一个值为 NULL, 则返回结果就为 NULL
mysql> select least (1,2,3),least ('a','b','c');
+---------------+---------------------+
| least (1,2,3) | least ('a','b','c') |
+---------------+---------------------+
| 1 | a |
+---------------+---------------------+
1 row in set (0.00 sec)
mysql> select greatest (1,2,3),greatest('a','b','c'),greatest(8,9,null);
+------------------+-----------------------+--------------------+
| greatest (1,2,3) | greatest('a','b','c') | greatest(8,9,null) |
+------------------+-----------------------+--------------------+
| 3 | c | NULL |
+------------------+-----------------------+--------------------+
1 row in set (0.00 sec)
mysql> select least (1,2,3),least ('a','b','c'),least(1,'a',null);
+---------------+---------------------+-------------------+
| least (1,2,3) | least ('a','b','c') | least(1,'a',null) |
+---------------+---------------------+-------------------+
| 1 | a | NULL |
+---------------+---------------------+-------------------+
1 row in set, 1 warning (0.00 sec)
##数字与字符不能直接比较
mysql> select least (1,'a');
+---------------+
| least (1,'a') |
+---------------+
| 0 |
+---------------+
1 row in set, 1 warning (0.00 sec)
#IN、NOT IN用法
#IN 判断一个值是否在对应的列表中,如果是返回 1,否则返回 0。
#NOT IN 判断一个值是否不在对应的列表中,如果不在返回 1,否则返回 0
mysql> select 2 in (1,2,3,4),'c' not in ('a','b','c');
+----------------+--------------------------+
| 2 in (1,2,3,4) | 'c' not in ('a','b','c') |
+----------------+--------------------------+
| 1 | 0 |
+----------------+--------------------------+
1 row in set (0.00 sec)
#LIKE、NOT LIKE用法
#LIKE 用来匹配字符串,如果匹配成功则返回 1,反之返回 0。LIKE 支持两种通配符:’%’ 用于匹配任意数目的字符,而’_’只能匹配一个字符。
#NOT LIKE 与 LIKE 相反,如果没有匹配成功则返回 1,反之返回 0
mysql> select 'aaa' like 'a__','kooo'like 'ko%','etc' not like 'et_';
+------------------+------------------+----------------------+
| 'aaa' like 'a__' | 'kooo'like 'ko%' | 'etc' not like 'et_' |
+------------------+------------------+----------------------+
| 1 | 1 | 0 |
+------------------+------------------+----------------------+
1 row in set (0.00 sec)
逻辑运算符
逻辑运算符又被称为布尔运算符,通常用来判断表达式的真假,如果为真返回 1,否则返回 0,真和假也可以用 TRUE 和 FALSE 表示。MySQL 中支持使用的逻辑运算符有四种
运算符 | 描述 |
NOT 或 ! | 逻辑非 |
AND 或 && | 逻辑与 |
OR 或 II | 逻辑或 |
XOR | 逻辑异或 |
这里有一张表,需要先熟悉表关系,才能进行以下操作
在逻辑预算符中,所有的值只有1和0,有了这个概念后,可以看以下操作
逻辑非
逻辑运算符中最简单的运算符就是逻辑非,逻辑非使用 NOT 或!表示。逻辑非将跟在它后面的逻辑测试取反,把真变为假,把假变为真
如果 NOT 后面的操作数为 0 时,所得值为 1;如果操作数为非 0 时,所得值为 0;如果操作数为 NULL 时,所得值为 NULL
mysql> select not 2,!3,not 0,!(4-4),not null;
+-------+----+-------+--------+----------+
| not 2 | !3 | not 0 | !(4-4) | not null |
+-------+----+-------+--------+----------+
| 0 | 0 | 1 | 1 | NULL |
+-------+----+-------+--------+----------+
1 row in set (0.00 sec)
not 2,!3可以看成以下:
not 1,not 3
#在逻辑预算符中,所有的值只有1和0
逻辑与
#逻辑与通常用于判断两个值或多个值的有效性,如果所有值都是真返回 1,否则返回 0,逻辑与使用 AND 或者&&表示
mysql> select 2 and 3,4 && 0,0 and 0,1 and null,0 and null;
+---------+--------+---------+------------+------------+
| 2 and 3 | 4 && 0 | 0 and 0 | 1 and null | 0 and null |
+---------+--------+---------+------------+------------+
| 1 | 0 | 0 | NULL | 0 |
+---------+--------+---------+------------+------------+
1 row in set (0.00 sec)
#总结:非0值与null比较,输出null,0与null比较,输出0
逻辑或
逻辑或表示包含的操作数,任意一个为非零值并且不是 NULL 值时,返回 1,否则返回0
逻辑或通常使用 OR 或者||来表示
虽说OR 或 II 可以表示逻辑或,但是||确不是那么靠谱,建议不要使用,比如:
mysql> select 2 or 3, 2 || 3;
+--------+--------+
| 2 or 3 | 2 || 3 |
+--------+--------+
| 1 | 23 |
+--------+--------+
1 row in set (0.00 sec)
##可以清晰的看出,输出结果23一定是不对的
mysql> select 5 or 0,0 or 0,0 or null,1 or null;
+--------+--------+-----------+-----------+
| 5 or 0 | 0 or 0 | 0 or null | 1 or null |
+--------+--------+-----------+-----------+
| 1 | 0 | NULL | 1 |
+--------+--------+-----------+-----------+
1 row in set (0.00 sec)
mysql> select 'a' or 'b','a' || 'b';
+------------+------------+
| 'a' or 'b' | 'a' || 'b' |
+------------+------------+
| 0 | ab |
+------------+------------+
1 row in set, 2 warnings (0.00 sec)
#总结:逻辑或中,1和null比较输出1,0和null比较输出null,不支持字符比较
#为什么1与null比较输出的是1?
或运算只要有一个成立,后面就不会再去看了,因为1已经成立,后面的null根本没有被加载,计算机就是这样
反观,0与null,因为0是空值,不会输出,所以计算机看到的是null。
逻辑异或
两个非 NULL 值的操作数,如果两者都是 0 或者都是非 0,则返回 0;如果一个为 0, 另一个为非 0,则返回结果为 1
当任意一个值为 NULL 时,返回值为 NULL
mysql> select 2 xor 3,0 xor 0,0 xor null,1 xor null;
+---------+---------+------------+------------+
| 2 xor 3 | 0 xor 0 | 0 xor null | 1 xor null |
+---------+---------+------------+------------+
| 0 | 0 | NULL | NULL |
+---------+---------+------------+------------+
1 row in set (0.00 sec)
位运算符
位运算符实际上是对二进制数进行计算的运算符。MySQL 内位运算会先将操作数变成二进制格式,然后进行位运算,最后在将计算结果从二进制变回到十进制格式,方便用户查看。MySQL 支持 6 种位运算符
|
运算符 | 描述 |
& | 按位与 |
I | 按位或 |
~ | 按位取反 |
^ | 按位异或 |
<< | 按位左移 |
>> | 按位右移 |
mysql> select 10 & 15,10 | 15,10 ^ 15,5 & ~1;
+---------+---------+---------+--------+
| 10 & 15 | 10 | 15 | 10 ^ 15 | 5 & ~1 |
+---------+---------+---------+--------+
| 10 | 15 | 5 | 4 |
+---------+---------+---------+--------+
1 row in set (0.00 sec)
#与运算就是且运算,参考上面的表,进行且运算
#按位与运算(&),是对应的二进制位都是 1 的,它们的运算结果为 1,否则为 0,所以 10 & 15 的结果为 10
#10 转换为二进制数是 1010, 15 转换为二进制数是 1111
1010
1111
1010=10
#按位或运算(|),是对应的二进制位有一个或两个为1的,运算结果为1,否则为0, 所以10 | 15的结果为15
1010
1111
1111=15
#按位异或运算(^),是对应的二进制位不相同时,运算结果1,否则为0,所以10 ^ 15的结果为5
1010
1111
0101=5
#按位取反(~),是对应的二进制数逐位反转,即 1 取反后变为 0, 0 取反后变为 1
原~1为 0001,取反后为1110
0101
1110
0100=4
#对数字进行左移或右移的运算
#左移或右移运算符,都是将数转换为二进制后,然后在左移或右移指定的位数,超出的位数将被移除并丢弃,空出来的位置用 0 补齐
mysql> select 1<<2,2<<2,1>>2,2>>2,15>>2;
+------+------+------+------+-------+
| 1<<2 | 2<<2 | 1>>2 | 2>>2 | 15>>2 |
+------+------+------+------+-------+
| 4 | 8 | 0 | 0 | 3 |
+------+------+------+------+-------+
1 row in set (0.00 sec)
###下面解释左移
1原本位 0001
1左移后 0100=4
2原本位 0010
2左移后 1000=8
#总结:左移就是在末尾加上几个零,左移几位加几个零,然后换算成2进制
###下面解释右移
1原本位 0001
1右移后 0000|01 去掉01后=0000 所以输出0
2原本位 0010
2右移后 0000|10 去掉10后=0000 所以输出0
15原本位 1111
15右移后 0011|11 去掉11后=0011 所以输出3
运算符的优先级
不管哪种运算符,在使用过程中都有优先级问题。运算符的优先级决定了不同的运 算符在计算过程中的先后顺序。
级别高的运算符会先进行计算,如果运算符的级别相同,MySQL 会按照顺序从左到右依次进行计算。如果不确定所使用的运算符的优先级,可以使用()改变优先级
优先级 | 运算符 | 优先级 | 运算符 | |
1 | ! | 8 | I | |
2 | ~ | 9 | =,<=>,>=,>,<=,<,<>,!=,IS,LIKE,REGEXP,IN | |
3 | ^ | 10 | BETWEEN,CASE,WHEN,THEN,ELSE | |
4 | * , /(DIV), %(MOD) | 11 | NOT | |
5 | +,- | 12 | &&,AND | |
6 | >>,<< | 13 | II,OR,XOR | |
7 | & | 14 | := |
数据库函数
数据库内存储的记录,经常要进行一系列的算术操作,所以 MySQL 支持很多数学函数。常用的数学函数如表|
数学函数 | 描述 |
abs(x) | 返回 x 的绝对值 |
rand() | 返回 0 到 1 的随机数 |
mod(x,y) | 返回 x 除以 y 以后的余数 |
power(x,y) | 返回 x 的 y 次方 |
round(x) | 返回离 x 最近的整数 |
round(x,y) | 保留x 的y 位小数四舍五入后的值 |
sqrt(x) | 返回 x 的平方根 |
truncate(x,y) | 返回数字 x 截断为 y 位小数的值 |
ceil(x) | 返回大于或等于 x 的最小整数 |
floor(x) | 返回小于或等于 x 的最大整数 |
greatest(x1,x2…) | 返回集合中最大的值 |
least(x1,x2…) | 返回集合中最小的值 |
具体操作和注释结合下面列子看
# abs(x) 返回 x 的绝对值
mysql> select abs(-100);
+-----------+
| abs(-100) |
+-----------+
| 100 |
+-----------+
1 row in set (0.00 sec)
#rand() 返回 0 到 1 的随机数
#rand()只能取到0,不能够取到1,最大的值是无线接近1,比如0.99999999
mysql> select rand();
+---------------------+
| rand() |
+---------------------+
| 0.40061400122997726 |
+---------------------+
1 row in set (0.00 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.4993908829050054 |
+--------------------+
1 row in set (0.00 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.9773895898623295 |
+--------------------+
1 row in set (0.00 sec)
#如果你想取0-100之间的值,可以结合使用,但是取不到100,最多可取99.9999999
mysql> select rand()*100;
+-------------------+
| rand()*100 |
+-------------------+
| 84.01506690682385 |
+-------------------+
1 row in set (0.00 sec)
mysql> select rand()*100;
+-------------------+
| rand()*100 |
+-------------------+
| 86.20946229082482 |
+-------------------+
1 row in set (0.01 sec)
#mod(x,y) 返回 x 除以 y 以后的余数
mysql> select mod(7,2);
+----------+
| mod(7,2) |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
#power(x,y) 返回 x 的 y 次方
mysql> select power(2,3);
+------------+
| power(2,3) |
+------------+
| 8 |
+------------+
1 row in set (0.00 sec)
#round(x) 返回离 x 最近的整数
mysql> select round(1.5);
+------------+
| round(1.5) |
+------------+
| 2 |
+------------+
1 row in set (0.00 sec)
mysql> select round(1.4);
+------------+
| round(1.4) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql> select round(1.6);
+------------+
| round(1.6) |
+------------+
| 2 |
+------------+
1 row in set (0.00 sec)
#总结:采用四舍五入算法
#round(x,y) 保留x 的y 位小数四舍五入后的值
#后面加,号+数字,保留小数点后面几位
mysql> select round(1.49,1);
+---------------+
| round(1.49,1) |
+---------------+
| 1.5 |
+---------------+
1 row in set (0.00 sec)
mysql> select round(1.4449,3);
+-----------------+
| round(1.4449,3) |
+-----------------+
| 1.445 |
+-----------------+
1 row in set (0.00 sec)
#sqrt(x) 返回 x 的平方根
mysql> select sqrt(9);
+---------+
| sqrt(9) |
+---------+
| 3 |
+---------+
1 row in set (0.00 sec)
mysql> select sqrt(7);
+--------------------+
| sqrt(7) |
+--------------------+
| 2.6457513110645907 |
+--------------------+
1 row in set (0.00 sec)
#truncate(x,y) 返回数字 x 截断为 y 位小数的值
mysql> select truncate(1.449,2);
+-------------------+
| truncate(1.449,2) |
+-------------------+
| 1.44 |
+-------------------+
1 row in set (0.00 sec)
mysql> select truncate(1.44449,4);
+---------------------+
| truncate(1.44449,4) |
+---------------------+
| 1.4444 |
+---------------------+
1 row in set (0.00 sec)
#总结:意思就是保留小数点后几位
#ceil(x) 返回大于或等于 x 的最小整数
mysql> select ceil(1.1),ceil(1.9);
+-----------+-----------+
| ceil(1.1) | ceil(1.9) |
+-----------+-----------+
| 2 | 2 |
+-----------+-----------+
1 row in set (0.00 sec)
#总结:向上取整
floor(x) 返回小于或等于 x 的最大整数
mysql> select floor(1.1),floor(1.9);
+------------+------------+
| floor(1.1) | floor(1.9) |
+------------+------------+
| 1 | 1 |
+------------+------------+
1 row in set (0.00 sec)
#总结:向下取整
#greatest(x1,x2...) 返回集合中最大的值
mysql> select greatest (1,2,3,15,19);
+------------------------+
| greatest (1,2,3,15,19) |
+------------------------+
| 19 |
+------------------------+
1 row in set (0.00 sec)
#least(x1,x2...) 返回集合中最小的值
mysql> select least (1,2,3,15,19);
+---------------------+
| least (1,2,3,15,19) |
+---------------------+
| 1 |
+---------------------+
1 row in set (0.00 sec)
聚合函数
MySQL 数据库函数中专门有一组函数是特意为库内记录求和或者对表中的数据进行集中概括而设计的,这些函数被称作聚合函数。常见的聚合函数
聚合函数 | 描述 |
avg() | 返回指定列的平均值 |
count() | 返回指定列中非 NULL 值的个数 |
min() | 返回指定列的最小值 |
max() | 返回指定列的最大值 |
sum(x) | 返回指定列的所有值之和 |
##关于 count(),这里请仔细看一下
##首先我们搭建一下环境
mysql> create table z(name varchar(20) not null,score varchar(10) default'',id varchar(5));
mysql> desc z;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(20) | NO | | NULL | |
| score | varchar(10) | YES | | | |
| id | varchar(5) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
mysql> insert into z (name) values (2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into z (name) values (1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from z;
+------+-------+------+
| name | score | id |
+------+-------+------+
| 2 | | NULL |
| 1 | | NULL |
+------+-------+------+
2 rows in set (0.00 sec)
##接下来看一下‘’和null在统计中的区别
mysql> select count(score) from z;
+--------------+
| count(score) |
+--------------+
| 2 |
+--------------+
1 row in set (0.00 sec)
mysql> select count(id) from z;
+-----------+
| count(id) |
+-----------+
| 0 |
+-----------+
1 row in set (0.00 sec)
##总结:在count()中,空值会被统计,而null不会
mysql> select * from player;
+------+----------------------+-------+
| id | name | level |
+------+----------------------+-------+
| 1 | 修欧拉卡 | 10 |
| 2 | 起风了 | 10 |
| 3 | 吊打低V | 15 |
| 4 | 小花 | 14 |
| 5 | 小舞 | 35 |
| 15 | 新五皇·白胡子 | 46 |
| 30 | 抢宝真多呀 | 47 |
| 51 | 新五皇·暴雪 | 45 |
| 63 | 新五皇–敬神 | 46 |
| 199 | D 丶狙击王 | 46 |
| 238 | sagou 轰总 | 7 |
| 272 | D 丶抢人头辅助 | 45 |
| 298 | 唐三 | 46 |
| 448 | useless | 1 |
| 713 | guess | 25 |
| 795 | senoku | 15 |
| 1735 | oooooo | 1 |
| 1979 | Theshy | 24 |
| 2237 | leslieF | 3 |
| 2460 | shirley | 1 |
| 2718 | ooo | 1 |
+------+----------------------+-------+
mysql> select sum(level) as sum_level from player;
+-----------+
| sum_level |
+-----------+
| 483 |
+-----------+
1 row in set (0.00 sec)
mysql>select max(level) as max_level from player;
+-----------+
| max_level |
+-----------+
| 47 |
+-----------+
1 row in set (0.00 sec)
mysql>select min(level) as min_level from player;
+-----------+
| min_level |
+-----------+
| 1 |
+-----------+
1 row in set (0.00 sec)
字符串函数
常用函数不仅包括数学函数和聚合函数,还包含字符串函数,MySQL 为字符串的相关操作设计了丰富的字符串函数。常用的字符串函数如表
字符串函数 | 描述 |
length(x) | 返回字符串 x 的长度 |
trim() | 返回去除指定格式的值 |
concat(x,y) | 将提供的参数 x 和 y 拼接成一个字符串 |
upper(x) | 将字符串 x 的所有字母变成大写字母 |
lower(x) | 将字符串 x 的所有字母变成小写字母 |
left(x,y) | 返回字符串 x 的前 y 个字符 |
right(x,y) | 返回字符串 x 的后 y 个字符 |
repeat(x,y) | 将字符串 x 重复 y 次 |
space(x) | 返回 x 个空格 |
replace(x,y,z) | 将字符串 z 替代字符串 x 中的字符串 y |
strcmp(x,y) | 比较 x 和 y,返回的值可以为-1,0,1 |
substring(x,y,z) | 获取从字符串 x 中的第 y 个位置开始长度为 z 的字符串 |
reverse(x) | 将字符串 x 反转 |
# length(x) 返回字符串 x 的长度
mysql> select length('anvdd');
+-----------------+
| length('anvdd') |
+-----------------+
| 5 |
+-----------------+
1 row in set (0.00 sec)
##同时,空格也算长度,不管放在哪里
mysql> select length('anvdd ');
+------------------+
| length('anvdd ') |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec)
mysql> select length('anv dd');
+------------------+
| length('anv dd') |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec)
mysql> select length('an v dd');
+-------------------+
| length('an v dd') |
+-------------------+
| 7 |
+-------------------+
1 row in set (0.00 sec)
#控制不算长度
mysql> select length('');
+------------+
| length('') |
+------------+
| 0 |
+------------+
1 row in set (0.00 sec)
#null显示null值
mysql> select length(null);
+--------------+
| length(null) |
+--------------+
| NULL |
+--------------+
1 row in set (0.00 sec)
#加‘’变为字符串,输出4个长度
mysql> select length('null');
+----------------+
| length('null') |
+----------------+
| 4 |
+----------------+
1 row in set (0.00 sec)
#trim() 返回去除指定格式的值
mysql> select length(trim('a b c'));
+-----------------------+
| length(trim('a b c')) |
+-----------------------+
| 5 |
+-----------------------+
1 row in set (0.01 sec)
mysql> select length(trim('a b c '));
+------------------------+
| length(trim('a b c ')) |
+------------------------+
| 5 |
+------------------------+
1 row in set (0.00 sec)
mysql> select length(trim(' a b c '));
+-------------------------+
| length(trim(' a b c ')) |
+-------------------------+
| 5 |
+-------------------------+
1 row in set (0.00 sec)
#总结:结合length()使用,只能去除头和尾的空格
##单独使用情况下:
mysql> select trim('a' 'b' 'c');
+-------------------+
| trim('a' 'b' 'c') |
+-------------------+
| abc |
+-------------------+
1 row in set (0.01 sec)
mysql> select trim('a b c');
+---------------+
| trim('a b c') |
+---------------+
| a b c |
+---------------+
1 row in set (0.00 sec)
mysql> select trim('a b c ');
+----------------+
| trim('a b c ') |
+----------------+
| a b c |
+----------------+
1 row in set (0.00 sec)
#总结,也只能去除头和尾的空格
#concat(x,y) 将提供的参数 x 和 y 拼接成一个字符串
mysql> select concat('aaa','bbb');
+---------------------+
| concat('aaa','bbb') |
+---------------------+
| aaabbb |
+---------------------+
1 row in set (0.00 sec)
mysql> select length(concat('abc','def'));
+-----------------------------+
| length(concat('abc','def')) |
+-----------------------------+
| 6 |
+-----------------------------+
1 row in set (0.00 sec)
upper(x) 将字符串 x 的所有字母变成大写字母
lower(x) 将字符串 x 的所有字母变成小写字母
mysql> select upper('aaa'),lower('BBB');
+--------------+--------------+
| upper('aaa') | lower('BBB') |
+--------------+--------------+
| AAA | bbb |
+--------------+--------------+
1 row in set (0.00 sec)
left(x,y) 返回字符串 x 的前 y 个字符
right(x,y) 返回字符串 x 的后 y 个字符
mysql> select left(1234578,3),right(12345678,2);
+-----------------+-------------------+
| left(1234578,3) | right(12345678,2) |
+-----------------+-------------------+
| 123 | 78 |
+-----------------+-------------------+
1 row in set (0.00 sec)
mysql> select left('aaabcd',3),right('bcdaa',2);
+------------------+------------------+
| left('aaabcd',3) | right('bcdaa',2) |
+------------------+------------------+
| aaa | aa |
+------------------+------------------+
1 row in set (0.00 sec)
#总结:所有的字符串都需要加‘',否则Mysql不识别
#repeat(x,y) 将字符串 x 重复 y 次
mysql> select repeat('abc',3);
+-----------------+
| repeat('abc',3) |
+-----------------+
| abcabcabc |
+-----------------+
1 row in set (0.00 sec)
#扩展用法
mysql> select length(repeat('abc',3));
+-------------------------+
| length(repeat('abc',3)) |
+-------------------------+
| 9 |
+-------------------------+
1 row in set (0.00 sec)
#space(x) 返回 x 个空格
mysql> select length(concat('abc',space(3),'abc'));
+--------------------------------------+
| length(concat('abc',space(3),'abc')) |
+--------------------------------------+
| 9 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> select concat('abc',space(5),'abc');
+------------------------------+
| concat('abc',space(5),'abc') |
+------------------------------+
| abc abc |
+------------------------------+
1 row in set (0.01 sec)
#replace(x,y,z) 将字符串 z 替代字符串 x 中的字符串 y
mysql> select replace('12211','22','11');
+----------------------------+
| replace('12211','22','11') |
+----------------------------+
| 11111 |
+----------------------------+
1 row in set (0.01 sec)
#strcmp(x,y) 比较 x 和 y,返回的值可以为-1,0,1
mysql> select strcmp(4,5);
+-------------+
| strcmp(4,5) |
+-------------+
| -1 |
+-------------+
1 row in set (0.00 sec)
mysql> select strcmp(4,3);
+-------------+
| strcmp(4,3) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select strcmp(4,4);
+-------------+
| strcmp(4,4) |
+-------------+
| 0 |
+-------------+
1 row in set (0.00 sec)
#总结:从左往右比,相同为0,小于为-1,大于为1
#substring(x,y,z) 获取从字符串 x 中的第 y 个位置开始长度为 z 的字符串
mysql> select substring('123456',3,3);
+-------------------------+
| substring('123456',3,3) |
+-------------------------+
| 345 |
+-------------------------+
1 row in set (0.00 sec)
mysql> select substring('123456789',3,5);
+----------------------------+
| substring('123456789',3,5) |
+----------------------------+
| 34567 |
+----------------------------+
1 row in set (0.00 sec)
#总结:从第几个开始,包含这个开始的位数
#reverse(x) 将字符串 x 反转
mysql> select reverse('abc');
+----------------+
| reverse('abc') |
+----------------+
| cba |
+----------------+
1 row in set (0.01 sec)
mysql> select reverse('bbs');
+----------------+
| reverse('bbs') |
+----------------+
| sbb |
+----------------+
1 row in set (0.00 sec)
日期时间函数
MySQL 也支持日期时间处理,提供了很多处理日期和时间的函数。一些常用的日期时间函数
字符串函数 | 描述 |
curdate() | 返回当前时间的年月日 |
curtime() | 返回当前时间的时分秒 |
now() | 返回当前时间的日期和时间 |
month(x) | 返回日期 x 中的月份值 |
week(x) | 返回日期 x 是年度第几个星期 |
hour(x) | 返回 x 中的小时值 |
minute(x) | 返回 x 中的分钟值 |
second(x) | 返回 x 中的秒钟值 |
dayofweek(x) | 返回 x 是星期几,1 星期日,2 星期一 |
dayofmonth(x) | 计算日期 x 是本月的第几天 |
dayofyear(x) | 计算日期 x 是本年的第几天 |
mysql>select curdate(),curtime(),now(),month('2020-02-09'), week('2020-02-09'), hour('21:13:53');
+------------+-----------+---------------------+---------------------+--------------------+------------------+
| curdate() | curtime() | now() | month('2020-02-09') | week('2020-02-09') | hour('21:13:53') |
+------------+-----------+---------------------+---------------------+--------------------+------------------+
| 2020-02-09 | 21:14:34 | 2020-02-09 21:14:34 | 2 | 6 |
21 |
+------------+-----------+---------------------+---------------------+--------------------+------------------+
1 row in set (0.00 sec)
mysql>select minute('21:13:53'),second('21:13:53'), dayofweek('2020-02-09'), dayofmonth('2020-02-09'), dayofyear('2020-02-09');
+--------------------+--------------------+-------------------------+--------------------------+-------------------------+
| minute('21:13:53') | second('21:13:53') | dayofweek('2020-02-09') | dayofmonth('2020-02-09') | dayofyear('2020-02-09') |
+--------------------+--------------------+-------------------------+--------------------------+-------------------------+
| 13 | 53 | 1 |
9 | 40 |
+--------------------+--------------------+-------------------------+--------------------------+-------------------------+
1 row in set (0.00 sec)