高级sql语句应用大全(常用查询、NULL值、正则、运算符、内外链接和数据库函数,以及存储过程)
MySQL进阶查询
1.1:常用查询介绍
对 MySQL 数据库的查询,除了基本的查询外,有时候需要对查询的结果集进行处理。
1.1.1:按关键字排序
- 使用order by语句来实现排序
- 排序可针对一个或多个字段
- ASC:升序,默认排序方式
- DESC:降序
语法结构:
select column1,column2,.....from table_name order by column1,column2,...asc|desc;
- 按单字段排序
mysql> select * from info where score>=80 order by score desc;
+----+----------+-------+---------+
| id | name | score | address |
+----+----------+-------+---------+
| 2 | lisi | 90.00 | nanjing |
| 4 | zhouliu | 90.00 | nanjing |
| 1 | zhangsan | 80.00 | beijing |
+----+----------+-------+---------+
3 rows in set (0.00 sec)
- 按多字段排序
mysql> select * from info where score>=80 order by score desc,id desc;
+----+----------+-------+---------+
| id | name | score | address |
+----+----------+-------+---------+
| 4 | zhouliu | 90.00 | nanjing | '在score=90的情况下,按照id降序排列'
| 2 | lisi | 90.00 | nanjing |
| 1 | zhangsan | 80.00 | beijing |
+----+----------+-------+---------+
3 rows in set (0.00 sec)
'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 用降序;'
1.1.2:对结果进行分组
-
通过 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 value group by column_name;
- group by分组
mysql> select count(name),score from info where score>=70 group by score;
+-------------+-------+
| count(name) | score |
+-------------+-------+
| 2 | 70.00 |
| 1 | 80.00 |
| 2 | 90.00 |
+-------------+-------+
3 rows in set (0.00 sec)
- group by结合order by
mysql> select count(name),score from info where score>=70 group by score order by score desc;
'按照score降序的方式进行分组'
+-------------+-------+
| count(name) | score |
+-------------+-------+
| 2 | 90.00 |
| 1 | 80.00 |
| 2 | 70.00 |
+-------------+-------+
3 rows in set (0.00 sec)
1.1.3:限制结果条目
- 在使用 MySQL SELECT 语句进行查询时,结果集返回的是所有匹配的记录。有时候仅需要返回第一行或者前几行,这时候就需要用到 LIMIT 子句。
- 使用limit语句限制条目
语法结构:
SELECT column1, column2, ... FROM table_name LIMIT [offset,] number
'[offset]表示位置偏移量,从0开始,number表示返回记录行的最大数目'
- 不从第一条开始取值
mysql> select * from info limit 1,3; '从第2条记录开始显示之后的3条数据'
+----+---------+-------+---------+
| id | name | score | address |
+----+---------+-------+---------+
| 2 | lisi | 90.00 | nanjing |
| 3 | wangwu | 70.00 | beijing |
| 4 | zhouliu | 90.00 | nanjing |
+----+---------+-------+---------+
3 rows in set (0.00 sec)
- 查询表的前三名的学会信息
mysql> select * from info order by score desc limit 3;
+----+----------+-------+---------+
| id | name | score | address |
+----+----------+-------+---------+
| 2 | lisi | 90.00 | nanjing |
| 4 | zhouliu | 90.00 | nanjing |
| 1 | zhangsan | 80.00 | beijing |
+----+----------+-------+---------+
3 rows in set (0.00 sec)
1.1.4:设置别名
- 使用AS语句设置别名,关键字AS可省略
- 设置别名时,保证不能与苦衷其他表或字段名称冲突
别名语法结构:
SELECT column_name AS alias_nameFROM table_name; '列的别名'
SELECT column_name(s) FROM table_name AS alias_name; '表的别名'
'原字段或者表名在库内不会被改变'
- AS的用法
mysql> select i.* from info as i limit 1; '作为别名'
+----+----------+-------+---------+
| id | name | score | address |
+----+----------+-------+---------+
| 1 | zhangsan | 80.00 | beijing |
+----+----------+-------+---------+
1 row in set (0.00 sec)
mysql> select i.* from info i limit 1; 'as可省略'
+----+----------+-------+---------+
| id | name | score | address |
+----+----------+-------+---------+
| 1 | zhangsan | 80.00 | beijing |
+----+----------+-------+---------+
1 row in set (0.00 sec)
mysql> create table tmp as select * from info; 'as作为连接语句的操作符,克隆'
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
- 注意:
- 在为表设置别名时,要保证别名不能与数据库中的其他表的名称冲突。
- 列的别名是在结果中有显示的,而表的别名在结果中没有显示,只在 执行查询时使用。
1.1.5:插入字段
mysql> alter table info add hobby int(3) not null;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc info;
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| name | char(10) | NO | | NULL | |
| score | decimal(5,2) | YES | | NULL | |
| address | varchar(50) | YES | | 未知 | |
| hobby | int(3) | NO | | NULL | |
+---------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
1.1.6:通配符
- 用于替换字符串中的部分字符
- 通常配合like一起使用,并协同where完成查询
- 常用通配符
- %表示零个、一个或多个
- _表示单个字符
- 通配符的用法
mysql> select name,score from info where name like 'z%'; '%的用法'
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
| zhouliu | 90.00 |
+----------+-------+
2 rows in set (0.00 sec)
mysql> select name,score from info where name like 'z______'; '_的用法'
+---------+-------+
| name | score |
+---------+-------+
| zhouliu | 90.00 |
+---------+-------+
1 row in set (0.00 sec)
mysql> select name,score from info where name like '_ho%'; '两者结合用法'
+---------+-------+
| name | score |
+---------+-------+
| zhouliu | 90.00 |
+---------+-------+
1 row in set (0.00 sec)
1.1.7:子查询
-
也称作内查询或者嵌套查询
-
先于主查询被执行,其结果将作为外层主查询的条件
-
在增删改查中都可以使用子查询
-
支持多层嵌套
-
IN语句是用来判断某个值是否在给定的结果集中
-
子查询的用法
mysql> select name,score from info where hobby in (select id from hob where hob_name='听音乐');
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
| lisi | 90.00 |
| zhouliu | 90.00 |
+----------+-------+
3 rows in set (0.00 sec)
mysql> select * from info where hobby in (select id from hob);
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 2 | lisi | 90.00 | nanjing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 4 | zhouliu | 90.00 | nanjing | 1 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
| 6 | heiba | 60.00 | nanjing | 2 |
+----+----------+-------+----------+-------+
6 rows in set (0.00 sec)
mysql> select name,score from info where hobby=(select id from hob where hob_namee='听音乐'); 'in换成=,同样也执行'
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
| lisi | 90.00 |
| zhouliu | 90.00 |
+----------+-------+
3 rows in set (0.00 sec)
'子查询内要查询的字段通常都是一个,查询后形成结果集供主查询使用。'
- 子查询用于insert语句中
insert into tmp select * from info where id in (select id from info);
- 子查询用于update语句中
update tmp set score=score+5 where id in (select a.id from (select id from tmp where score<80) a);
'相当于'
update tmp set score=score+5 where score <80;
- 子查询用于delete语句中
delete from tmp where id in (select a.id from (select id from tmp where score<80) a);
- EXIST 这个关键字在子查询时,主要用于判断子查询的结果集是否为空
mysql> select name,score from info where exists (select id from hob where hob_namme='看猫');
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
| lisi | 90.00 |
| wangwu | 70.00 |
| zhouliu | 90.00 |
| tianqi | 70.00 |
| heiba | 60.00 |
+----------+-------+
6 rows in set (0.00 sec)
'Exists 只能做select语句查询 查询结果为空不执行前面的,不为空执行'
1.2:NULL值
-
表示缺失的值
-
与数字0或者空白(spaces)是不同的
-
使用IS NULL或IS NOT NULL进行判断
-
NULL值和空值的区别
- 空值长度为0,不占空间;NULL值的长度为NULL,占用空间
- IS NULL无法判断空值
- 空值使用“="或者“<>"来处理
- COUNT()计算时,NULL会忽略,空值会加入计算
-
0表示false,1表示true与shell中$?变量相反0为true,1为false
mysql> create table num (id int(3) not null primary key auto_increment,name char(10));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into num (id,name) values (1,'tom');
Query OK, 1 row affected (0.00 sec)
mysql> insert into num (id) values (2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from num;
+----+------+
| id | name |
+----+------+
| 1 | tom |
| 2 | NULL |
+----+------+
2 rows in set (0.00 sec)
mysql> select count(id) from num;
+-----------+
| count(id) |
+-----------+
| 2 |
+-----------+
1 row in set (0.00 sec)
mysql> select count(name) from num;
+-------------+
| count(name) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> insert into num (id,name) values (3,'');
Query OK, 1 row affected (0.00 sec)
mysql> select * from num;
+----+------+
| id | name |
+----+------+
| 1 | tom |
| 2 | NULL |
| 3 | |
+----+------+
3 rows in set (0.00 sec)
mysql> select count(name) from num; '空值是会被加入到计算中'
+-------------+
| count(name) |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)
- NUll用法
mysql> select * from num where name is not null;
+----+------+
| id | name |
+----+------+
| 1 | tom |
| 3 | |
+----+------+
2 rows in set (0.00 sec)
1.3:正则表达式
-
MySQL 正则表达式通常是在检索数据库记录的时候,根据指定的匹配模式匹配记录中符合要求的特殊字符串。
-
MySQL 的正则表达式使用 REGEXP 这个关键字来指定正则表达式的匹配模式
-
常用匹配模式
^ | 匹配开始字符 | p1|p2 | 匹配p1或者p2 |
---|---|---|---|
$ | 匹配结束字符 | […] | 匹配字符集中的任意一个字符 |
. | 匹配任意单个字符 | [^…] | 匹配不在中括号内的任何字符 |
* | 匹配任意个前面的字符 | {n} | 匹配前面的字符串n次 |
+ | 匹配前面字符至少一次 | {n,m} | 匹配前面的字符串至少n次,至多m次 |
1.3.1:以特定字符串开头的记录
mysql> select * from info where name regexp '^z';
+----+----------+-------+---------+-------+
| id | name | score | address | hobby |
+----+----------+-------+---------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 4 | zhouliu | 90.00 | nanjing | 1 |
+----+----------+-------+---------+-------+
2 rows in set (0.00 sec)
1.3.2:以特定字符串结尾的记录
mysql> select * from info where name regexp 'u$';
+----+---------+-------+---------+-------+
| id | name | score | address | hobby |
+----+---------+-------+---------+-------+
| 3 | wangwu | 70.00 | beijing | 2 |
| 4 | zhouliu | 90.00 | nanjing | 1 |
+----+---------+-------+---------+-------+
2 rows in set (0.00 sec)
1.3.3:包含指定字符串的记录
mysql> select * from info where name regexp 'an';
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
+----+----------+-------+----------+-------+
3 rows in set (0.00 sec)
1.3.4:以“.”代替字符串中的任意一个字符的记录
mysql> select * from info where name regexp '.n';
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
+----+----------+-------+----------+-------+
3 rows in set (0.00 sec)
1.3.5:匹配包含或者关系的记录
mysql> select * from info where name regexp 'an|on';
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
+----+----------+-------+----------+-------+
3 rows in set (0.00 sec)
1.3.6:“*”匹配前面字符的任意多次
mysql> select * from info where name regexp 'an*';
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
| 6 | heiba | 60.00 | nanjing | 2 |
+----+----------+-------+----------+-------+
4 rows in set (0.00 sec)
1.3.7:“+”匹配前面字符至少一次
mysql> select * from info where name regexp 'an+';
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 80.00 | beijing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
+----+----------+-------+----------+-------+
3 rows in set (0.00 sec)
1.3.8:匹配指定字符集中的任意一个
mysql> select * from info where name regexp '^[a-x]';
+----+--------+-------+----------+-------+
| id | name | score | address | hobby |
+----+--------+-------+----------+-------+
| 2 | lisi | 90.00 | nanjing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
| 6 | heiba | 60.00 | nanjing | 2 |
+----+--------+-------+----------+-------+
4 rows in set (0.00 sec)
1.4:运算符
- 用于对记录中的字段值进行运算
- 运算符分类
- 算术运算符
- 比较运算符
- 逻辑运算符
- 位运算符
1.4.1:算术运算符
- mysql支持的算术运算符
- +加法
- -减法
- *乘法
- /除法
- %取余数
mysql> select 1+2,2*3,5-4,7%2,7/2;
+-----+-----+-----+------+--------+
| 1+2 | 2*3 | 5-4 | 7%2 | 7/2 |
+-----+-----+-----+------+--------+
| 3 | 6 | 1 | 1 | 3.5000 |
+-----+-----+-----+------+--------+
1 row in set (0.00 sec)
'除法会保留小数点的位数'
'在除法运算和求余数运算中,除数不能为0,若除数是0,返回的结果则为NULL。需要注意的是,如果有多个运算符,按照先乘除后加减的优先级进行运算,相同优先级的运算符没有先后顺序。'
'在 MySQL 的字段值内还有一种情况:某些字符串类型的字段存储的数字型字符串,这些字段在进行算术运算时将会被自动转换为数字的值。如果字符串的开始部分是数字,在转换时将被转换为这个数字。如果是既包含字符又包含数字得的混合字符串,无法转换为数字时,将被转换为0。'
-
注意点
-
在除法运算和求余数运算中,除数不能为0,若除数是0,返回的结果则为NULL。需要注意的是,如果有多个运算符,按照先乘除后加减的优先级进行运算,相同优先级的运算符没有先后顺序。
-
在 MySQL 的字段值内还有一种情况:某些字符串类型的字段存储的数字型字符串,这些字段在进行算术运算时将会被自动转换为数字的值。如果字符串的开始部分是数字,在转换时将被转换为这个数字。如果是既包含字符又包含数字得的混合字符串,无法转换为数字时,将被转换为0。
1.4.2:比较运算符
- 字符串的比较默认不区分大小写,可使用binary来区分
- 其中字符的比较是根据 ASCII 码来判断的,0为48,A是65,a为97
- 常用比较运算符
运算符 | 描述 | 运算符 | 描述 |
---|---|---|---|
= | 等于 | IS NOT NULL | 判断一个值是否不为 NULL |
> | 大于 | BETWEEN AND | 两者之间 |
< | 小于 | IN | 在集合中 |
>= | 大于等于 | LIKE | 通配符匹配 |
<= | 小于等于 | GREATEST | 两个或多个参数时返回最大值 |
!=或<> | 不等于 | LEAST | 两个或多个参数时返回最小值 |
IS NULL | 判断一个值是否为 NULL | REGEXP | 正则表达式 |
- 等于运算符
- 等号(=)是用来判断数字、字符串和表达式是否相等的,如果相等则返回 1,如果不相等则返回 0。
mysql> select 2=4,2='2','e'='e',(2+2)=(3+1),'a'=null;
+-----+-------+---------+-------------+----------+
| 2=4 | 2='2' | 'e'='e' | (2+2)=(3+1) | 'a'=null |
+-----+-------+---------+-------------+----------+
| 0 | 1 | 1 | 1 | NULL |
+-----+-------+---------+-------------+----------+
1 row in set (0.00 sec)
从以上查询可以看出来:
Ø 如果两者都是整数,则按照整数值进行比较。
Ø 如果一个整数一个字符串,则会自动将字符串转换为数字,再进行比较。
Ø 如果两者都是字符串,则按照字符串进行比较。
Ø 如果两者中至少有一个值是 NULL,则比较的结果是 NULL。
- 不等于运算符
- 不等于号有两种写法,分别是<>或者!=,用于针对数字、字符串和表达式不相等的比较。如果不相等则返回 1,如果相等则返回 0,这点正好跟等于的返回值相反。
mysql> select 'kfc'<>'bdqn',1<>2,3!=3,2.5!=2,null<>null;
+---------------+------+------+--------+------------+
| 'kfc'<>'bdqn' | 1<>2 | 3!=3 | 2.5!=2 | null<>null |
+---------------+------+------+--------+------------+
| 1 | 1 | 0 | 1 | NULL |
+---------------+------+------+--------+------------+
1 row in set (0.00 sec)
需要注意的是不等于运算符不能用于判断null。
- 大于、大于等于、小于、小于等于运算符
Ø 大于(>)运算符用来判断左侧的操作数是否大于右侧的操作数,若大于返回 1,否则返回 0,同样不能用于判断 NULL。
Ø 小于(<)运算符用来判断左侧的操作数是否小于右侧的操作数,若小于返回 1,否则返回 0,同样不能用于判断 NULL。
Ø 大于等于(>=)判断左侧的操作数是否大于等于右侧的操作数,若大于等于返回 1,否则返回 0,不能用于判断 NULL。
Ø 小于等于(<=)判断左侧的操作数是否小于等于右侧的操作数,若小于等于返回 1,否则返回 0,不能用于判断 NULL。
mysql> select 5>4,'a'>'b',2>=3,(2+3)>=(1+2),4.4<3,'x'<='y','u'>=null;
+-----+---------+------+--------------+-------+----------+-----------+
| 5>4 | 'a'>'b' | 2>=3 | (2+3)>=(1+2) | 4.4<3 | 'x'<='y' | 'u'>=null |
+-----+---------+------+--------------+-------+----------+-----------+
| 1 | 0 | 0 | 1 | 0 | 1 | NULL |
+-----+---------+------+--------------+-------+----------+-----------+
1 row in set (0.00 sec)
- between and
BETWEEN AND 比较运算通常用于判断一个值是否落在某两个值之间
mysql> select 4 between 2 and 6,5 between 5 and 10,'f' between 'a' and 'z';
+-------------------+--------------------+-------------------------+
| 4 between 2 and 6 | 5 between 5 and 10 | 'f' between 'a' and 'z' |
+-------------------+--------------------+-------------------------+
| 1 | 1 | 1 |
+-------------------+--------------------+-------------------------+
1 row in set (0.00 sec)
- least、greatest
Ø LEAST:当有两个或者多个参数时,返回其中的最小值。如果其中一个值为 NULL,则返回结果就为 NULL。
Ø GREATEST:当有两个或者多个参数时,返回其中的最大值。如果其中一个值为 NULL, 则返回结果就为 NULL。
mysql> select least(10,20,30),least ('a','b','c');
+-----------------+---------------------+
| least(10,20,30) | least ('a','b','c') |
+-----------------+---------------------+
| 10 | a |
+-----------------+-----
- in、not in
Ø IN 判断一个值是否在对应的列表中,如果是返回 1,否则返回 0。
NOT IN 判断一个值是否不在对应的列表中,如果不是返回 1,否则返回 0
mysql> select 2 in (2,3,4,5),'c' not in ('d','e');
+----------------+----------------------+
| 2 in (2,3,4,5) | 'c' not in ('d','e') |
+----------------+----------------------+
| 1 | 1 |
+----------------+----------------------+
1 row in set (0.00 sec)
1.4.3:逻辑运算符
- 又称为布尔运算符
- 用力判断表达式的真假
运算符 | 描述 |
---|---|
NOT 或 ! | 逻辑非 |
AND 或 && | 逻辑与 |
OR 或 || | 逻辑或 |
XOR | 逻辑异或 |
解释:
且 0&&0=0 1&&0=0 0&&1=0 1&&1=1
或 0||0=0 1||0=1 0||1=1 1||1
异或0^0=0 1^0=1 0^1=1 1^1=0
- 逻辑运算符的用法
'逻辑非'
mysql> select not 2,!3,not 0,!(4-4);
+-------+----+-------+--------+
| not 2 | !3 | not 0 | !(4-4) |
+-------+----+-------+--------+
| 0 | 0 | 1 | 1 |
+-------+----+-------+--------+
1 row in set (0.00 sec)
'逻辑与'
mysql> select 2 and 3,4 &&0,0 && null,1 and null;
+---------+-------+-----------+------------+
| 2 and 3 | 4 &&0 | 0 && null | 1 and null |
+---------+-------+-----------+------------+
| 1 | 0 | 0 | NULL |
+---------+-------+-----------+------------+
1 row in set (0.00 sec)
'逻辑或'
mysql> select 2 or 3,4 or 0,0 or null,1 or null;
+--------+--------+-----------+-----------+
| 2 or 3 | 4 or 0 | 0 or null | 1 or null |
+--------+--------+-----------+-----------+
| 1 | 1 | NULL | 1 |
+--------+--------+-----------+-----------+
1 row in set (0.00 sec)
'逻辑异或'
mysql> select 2 xor 3,0 xor 0,0 xor 5,1 xor null,null xor null;
+---------+---------+---------+------------+---------------+
| 2 xor 3 | 0 xor 0 | 0 xor 5 | 1 xor null | null xor null |
+---------+---------+---------+------------+---------------+
| 0 | 0 | 1 | NULL | NULL |
+---------+---------+---------+------------+---------------+
1 row in set (0.00 sec)
1.4.4:位运算符
- 位运算符实际上是对二进制数进行计算的运算符,MySQL 内位运算会先将操作数变成二进制格式,然后进行位运算,最后在将计算结果从二进制变回到十进制格式
运算符 | 描述 |
---|---|
& | 按位与 |
| | 按位或 |
~ | 按位取反 |
^ | 按位异或 |
<< | 按位左移 |
>> | 按位右移 |
'对数字进行按位与、或和取反运算'
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)
分析:
'10 转换为二进制数是1010, 15 转换为二进制数是1111。'
'按位与运算(&),是对应的二进制位都是1的,它们的运算结果为1,否则为0,所以 10 & 15 的结果为 10。'
'按位或运算(|),是对应的二进制位有一个或两个为1的,运算结果为1,否则为0,所以10 | 15 的结果为 15。'
'按位异或运算(^),是对应的二进制位不相同时,运算结果 1,否则为 0,所以 10 ^ 15的结果为 5。'
'按位取反(~),是对应的二进制数逐位反转,即 1 取反后变为 0, 0取反后变为 1。数字 1 的二进制是 0001,取反后变为 1110, 数字 5 的二进制是 0101,将 1110 和 0101进行求与操作,其结果是二进制的 0100,转换为十进制就是 4。'
1.4.5:运算符的优先级
优先级 | 运算符 | 优先级 | 运算符 |
---|---|---|---|
1 | ! | 8 | | |
2 | ~ | 9 | =,<=>,>=,>,<=,<,<>,!=,IS,LIKE,REGEXP,IN |
3 | ^ | 10 | BETWEEN,CASE,WHEN,THEN,ELSE |
4 | * , /(DIV), %(MOD) | 11 | NOT |
5 | +,- | 12 | &&,AND |
6 | >>,<< | 13 | ||,OR,XOR |
7 | & | 14 | := |
1.5:连接查询
- MySQL 的连接查询,通常都是将来自两个或多个表的行结合起来,基于这些表之间的共同字段,进行数据的拼接。
- 首先,要确定一个主表作为结果集
- 然后将其他表的行有选择性的连接到选定的主表结果集上。
- 使用较多的连接查询包括:内连接、外连接(左连接和右连接)。
1.5.1:内连接
- MySQL 中的内连接就是两张或多张表中同时符合某种条件的数据记录的组合。通常在FROM 子句中使用关键字 INNER JOIN 来连接多张表,并使用 ON 子句设置连接条件
语法结构:
select column_name(s) from table1 inneer join table2 on table1.column_name=table2.column_name;
- 内连接是系统默认的表连接,所以在 FROM 子句后可以省略 INNER 关键字,只使用关键字 JOIN。同时有多个表时,也可以连续使用 INNER JOIN 来实现多表的内连接,不过为了更好的性能,建议最好不要超过三个表。
- 原理图
1.5.2:左连接
- 左连接也可以被称为左外连接,在 FROM 子句中使用 LEFT JOIN 或者 LEFT OUTER JOIN 关键字来表示。左连接以左侧表为基础表,接收左表的所有行,并用这些行与右侧参考表中的记录进行匹配,也就是说匹配左表中的所有行以及右表中符合条件的行。
语法结构:
select * from table1 left join table2 on table1.column_name=table2.column_name;
- 原理图
从原理图可以看出,左连接中左表的记录将会全部表示出来,而右表只会显示符合搜索 条件的记录,也就是图中交叉的部分。右表记录不足的地方均为 NULL。
1.5.3:右链接
- 右连接也被称为右外连接,在 FROM 子句中使用 RIGHT JOIN 或者 RIGHT OUTER JOIN 关键字来表示。右连接跟左连接正好相反,它是以右表为基础表,用于接收右表中的所有行,并用这些记录与左表中的行进行匹配。也就是说匹配右表中的每一行及左表中符合条件的记录。
语法结构:
select * from table1 right join table2 on table1.column_name=table2.column_name;
- 原理图
二:数据库函数
- MySQL提供了实现各种功能的函数
- 常用的函数分类
- 数学函数
- 聚合函数
- 字符串函数
- 日期时间函数
2.1:数学函数
- 常用的数学函数
数学函数 | 描述 |
---|---|
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,…) | 返回集合中最小的值 |
- 示例
mysql> select abs(-1),abs(-3.14),abs(2);
+---------+------------+--------+
| abs(-1) | abs(-3.14) | abs(2) |
+---------+------------+--------+
| 1 | 3.14 | 2 |
+---------+------------+--------+
1 row in set (0.00 sec)
mysql> select rand();
+---------------------+
| rand() |
+---------------------+
| 0.45002595470289325 |
+---------------------+
1 row in set (0.00 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.5530919065262115 |
+--------------------+
1 row in set (0.00 sec)
mysql> select mod(11,3);
+-----------+
| mod(11,3) |
+-----------+
| 2 |
+-----------+
1 row in set (0.00 sec)
mysql> select power(3,2);
+------------+
| power(3,2) |
+------------+
| 9 |
+------------+
1 row in set (0.00 sec)
mysql> select round(1.49);
+-------------+
| round(1.49) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select round(1.50);
+-------------+
| round(1.50) |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)
mysql> select round(1.49,1);
+---------------+
| round(1.49,1) |
+---------------+
| 1.5 |
+---------------+
1 row in set (0.00 sec)
mysql> select sqrt(9);
+---------+
| sqrt(9) |
+---------+
| 3 |
+---------+
1 row in set (0.00 sec)
mysql> select sqrt(10);
+--------------------+
| sqrt(10) |
+--------------------+
| 3.1622776601683795 |
+--------------------+
1 row in set (0.00 sec)
mysql> select truncate (3.1415926,3);
+------------------------+
| truncate (3.1415926,3) |
+------------------------+
| 3.141 |
+------------------------+
1 row in set (0.00 sec)
mysql> select ceil(1.4);
+-----------+
| ceil(1.4) |
+-----------+
| 2 |
+-----------+
1 row in set (0.00 sec)
mysql> select floor(1.9);
+------------+
| floor(1.9) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
2.2:聚合函数
- 对表中数据记录进行集中概括而设计的都一类函数
- 常用的聚合函数
聚合函数 | 描述 |
---|---|
avg() | 返回指定列的平均值 |
count() | 返回指定列中非 NULL 值的个数 |
min() | 返回指定列的最小值 |
max() | 返回指定列的最大值 |
sum(x) | 返回指定列的所有值之和 |
- 示例
mysql> select sum(score) from info;
+------------+
| sum(score) |
+------------+
| 460.00 |
+------------+
1 row in set (0.00 sec)
mysql> select count(name) from info;
+-------------+
| count(name) |
+-------------+
| 6 |
+-------------+
1 row in set (0.00 sec)
mysql> select max(score) from info;
+------------+
| max(score) |
+------------+
| 90.00 |
+------------+
1 row in set (0.00 sec)
mysql> select min(score) from info;
+------------+
| min(score) |
+------------+
| 60.00 |
+------------+
1 row in set (0.00 sec)
2.3:字符串函数(重点)
- 常用的字符串函数
字符串函数 | 描述 |
---|---|
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 反转 |
- 示例
mysql> select length('abcd');
+----------------+
| length('abcd') |
+----------------+
| 4 |
+----------------+
1 row in set (0.00 sec)
mysql> select length('ab cd'); '空格是算字符串的'
+-----------------+
| length('ab cd') |
+-----------------+
| 5 |
+-----------------+
1 row in set (0.00 sec)
mysql> select trim(' abcd');
+----------------+
| trim(' abcd') |
+----------------+
| abcd |
+----------------+
1 row in set (0.00 sec)
mysql> select trim(' ab cd '); '只会去除前后的空格,中间的不会去除'
+--------------------+
| trim(' ab cd ') |
+--------------------+
| ab cd |
+--------------------+
1 row in set (0.00 sec)
mysql> select concat('abc','bdqn');
+----------------------+
| concat('abc','bdqn') |
+----------------------+
| abcbdqn |
+----------------------+
1 row in set (0.00 sec)
mysql> select concat('abc',' bdqn');
+-----------------------+
| concat('abc',' bdqn') |
+-----------------------+
| abc bdqn |
+-----------------------+
1 row in set (0.00 sec)
mysql> select concat('abc',trim(' bdqn')); '函数嵌套'
+-----------------------------+
| concat('abc',trim(' bdqn')) |
+-----------------------------+
| abcbdqn |
+-----------------------------+
1 row in set (0.00 sec)
mysql> select upper('abc'),lower('ABC');
+--------------+--------------+
| upper('abc') | lower('ABC') |
+--------------+--------------+
| ABC | abc |
+--------------+--------------+
1 row in set (0.00 sec)
mysql> select left('abcdefg',3); '截取前三个'
+-------------------+
| left('abcdefg',3) |
+-------------------+
| abc |
+-------------------+
1 row in set (0.00 sec)
mysql> select right('abcdefg',3); '截取后三个'
+--------------------+
| right('abcdefg',3) |
+--------------------+
| efg |
+--------------------+
1 row in set (0.00 sec)
mysql> select repeat('abc',2); '重复abc2次'
+-----------------+
| repeat('abc',2) |
+-----------------+
| abcabc |
+-----------------+
1 row in set (0.00 sec)
mysql> select concat('a',space('3'),'b'); '返回三个空格'
+----------------------------+
| concat('a',space('3'),'b') |
+----------------------------+
| a b |
+----------------------------+
1 row in set (0.00 sec)
mysql> select replace('hello','ll','uf');
+----------------------------+
| replace('hello','ll','uf') |
+----------------------------+
| heufo |
+----------------------------+
1 row in set (0.00 sec)
mysql> select strcmp(9,7);
+-------------+
| strcmp(9,7) |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select strcmp(27,7);
+--------------+
| strcmp(27,7) |
+--------------+
| -1 |
+--------------+
1 row in set (0.00 sec)
mysql> select strcmp(7,7);
+-------------+
| strcmp(7,7) |
+-------------+
| 0 |
+-------------+
1 row in set (0.00 sec)
mysql> select substring('abcdefg',3,4);
+--------------------------+
| substring('abcdefg',3,4) |
+--------------------------+
| cdef |
+--------------------------+
1 row in set (0.00 sec)
mysql> select reverse('abc');
+----------------+
| reverse('abc') |
+----------------+
| cba |
+----------------+
1 row in set (0.01 sec)
mysql> select upper(reverse('hello'));
+-------------------------+
| upper(reverse('hello')) |
+-------------------------+
| OLLEH |
+-------------------------+
1 row in set (0.00 sec)
2.4:日期时间函数
- 常用的日期时间函数
字符串函数 | 描述 |
---|---|
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();
+------------+
| curdate() |
+------------+
| 2020-08-25 |
+------------+
1 row in set (0.00 sec)
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 22:18:45 |
1 row in set (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2020-08-25 22:18:52 |
+---------------------+
1 row in set (0.00 sec)
mysql> select month(curdate());
+------------------+
| month(curdate()) |
+------------------+
| 8 |
+------------------+
1 row in set (0.00 sec)
mysql> select week(curdate());
+-----------------+
| week(curdate()) |
+-----------------+
| 34 |
+-----------------+
1 row in set (0.00 sec)
mysql> select month('2020-08-25');
+---------------------+
| month('2020-08-25') |
+---------------------+
| 8 |
+---------------------+
1 row in set (0.00 sec)
mysql> select hour(curtime());
+-----------------+
| hour(curtime()) |
+-----------------+
| 22 |
+-----------------+
1 row in set (0.00 sec)
mysql> select minute(curtime());
+-------------------+
| minute(curtime()) |
+-------------------+
| 20 |
+-------------------+
1 row in set (0.00 sec)
mysql> select second(curtime());
+-------------------+
| second(curtime()) |
+-------------------+
| 4 |
+-------------------+
1 row in set (0.00 sec)
mysql> select dayofyear(curdate());
+----------------------+
| dayofyear(curdate()) |
+----------------------+
| 238 |
+----------------------+
1 row in set (0.00 sec)
mysql> select dayofmonth(curdate());
+-----------------------+
| dayofmonth(curdate()) |
+-----------------------+
| 25 |
+-----------------------+
1 row in set (0.00 sec)
三:存储过程简介(重点)
- 是一组为了完成特定功能的SQL语句集合
- 比传统SQL速度更快、执行效率更高
- 存储过程的优点
- 执行一次后,会将生成的二进制代码驻留缓冲区,提高执行效率
- SQL语句加上控制语句的集任,灵活性高
- 在服务器端存储,客户端调用时,降低网络负载
- 可多次重复被调用,可随时修改,不影响客户端调用
- 可完成所有的数据库操作,也可控制数据库的信息访问权限
servlet是服务器容器,写了很多代码,sql语句嵌入在Java代码当中,你要去找远程的数据库服务器,而你在sql语句中写了很多select语句,然后发送给数据库,数据库执行sql语句再返回来。在这过程当中进行封装,通过网络,当SQL语句中子查询过多,使网络负载变大,高并发查询时阻塞严重。其次安全性,很多数据包通过封装传输,容易被截取。因此有了存储。
只要在JAVA代码中嵌入一个名字,将MyRole发送给对方就可以调用,执行SQL语句。从安全性上看,窃取者只能看到名字,而不会知道里面具体的操作。
3.1:创建存储过程
- 使用 CREATE PROCEDURE 语句创建存储过程
语法结构:
create procedure <过程名> ([过程参数[.....]]) <过程体> [过程参数[.....]] 格式 [in|out|inout] <参数名> <类型>
-
参数分为
- 输入参数:IN
- 输出参数:OUT
- 输入/输出参数:INOUT
-
存储过程的主题部分,被分为过程体
-
以BEGIN开始,以END结束,若只有一条SQL语句,则可以省略BEGIN-END
-
以DELIMIT开始和结束
语法格式:
mysql> DELIMITER $$
'省略存储过程其他步骤'
mysql> DELIMITER ;
'delimiter后有空格,必须有'
delimiter $$ '开始'
Create procedure 存储过程名(in 参数名 参数类型)
Begin
'\#定义变量'
Declare 变量名 变量类型
'\#变量赋值'
Set 变量名=值
Sql 语句1;
Sql 语句2;
.......
Sql 语句n;
End $
delimiter ; '结束'
'\#调用存储过程'
Call 存储过程名(实际参数)
'\#查询存储过程'
Show procedure status where db=’数据库’;
- 示例
'调用存储过程'
mysql> delimiter $$
mysql> create procedure MyRole() begin select name,score from info; end$$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
mysql> call MyRole;
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
| lisi | 90.00 |
| wangwu | 70.00 |
| zhouliu | 90.00 |
| tianqi | 70.00 |
| heiba | 60.00 |
+----------+-------+
6 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter $$
mysql> create procedure MySchool(in my_name varchar(10))
-> begin
-> select name,score from info where name=my_name;
-> end$$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> show procedure status where db='school'; '查询'
mysql> call MySchool('zhangsan'); '调用'
+----------+-------+
| name | score |
+----------+-------+
| zhangsan | 80.00 |
+----------+-------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter $$
mysql> create procedure MyUpdate(in my_score decimal(5,2)) 'score变量'
-> begin
-> declare hob int (3); '声明'
-> if my_score >= 75 then
-> set hob = 1;
-> else
-> set hob = 2;
-> end if;
-> update info set score=my_score,hobby=hob where name='zhangsan';
-> end$$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call MyUpdate(76); '修改为76分,hobby序号自动分配'
Query OK, 1 row affected (0.01 sec)
mysql> select * from info;
+----+----------+-------+----------+-------+
| id | name | score | address | hobby |
+----+----------+-------+----------+-------+
| 1 | zhangsan | 76.00 | beijing | 1 |
| 2 | lisi | 90.00 | nanjing | 1 |
| 3 | wangwu | 70.00 | beijing | 2 |
| 4 | zhouliu | 90.00 | nanjing | 1 |
| 5 | tianqi | 70.00 | hangzhou | 2 |
| 6 | heiba | 60.00 | nanjing | 2 |
+----+----------+-------+----------+-------+
6 rows in set (0.00 sec)
3.2:删除存储过程
语法格式:
Drop procedure 存储过程名;
- 示例
mysql> drop procedure MyRole; '删除存储过程'
Query OK, 0 rows affected (0.00 sec)
mysql> show procedure status where db='school';