这里写目录标题

  • 一,mysql进阶查询
  • 1,按关键字排序
  • (1)按单字段排序
  • (2)按多字段排序
  • 2,按结果进行分组
  • (1)group by 分组
  • (2)group by 结合order by
  • 3,限制结果条目
  • 二,MYSQL存储过程
  • 1, 通配符
  • 2,子查询
  • 3,NULL值
  • 4,正则表达式
  • 5,连接查询
  • 6,字符串函数
  • 三,存储过程简介
  • 1,创建存储过程
  • 2, 删除存储过程
  • 3,修改存储过程


一,mysql进阶查询

1,按关键字排序

(1)按单字段排序
  • 使用DRDER NY语句来实现排序
  • 排序可针对一个或者多个字段
  • ASC;升序,默认排序方式
  • DESC;降序
  • DRDER BY 的语法结构
select column1,column2... from 库名 order by column1,column2,... asc|desc;

mysql> create database lihuiuhi;
mysql> create table test(xuehao char(10) not null,nianling int(3) not null,xingming char(36) not null,chengji varchar(3) not null);
mysql> insert into test values(201001,17,'zhangsan',60),(201002,18,'lisi',70),(201003,19,'wangwu',80),(201004,18,'zhaoliu',88),(201005,17,'lilei',55);

默认升序
mysql> select chengji from test order by chengji;
降序
mysql> select chengji from test order by chengji desc;
加入条件的排序
mysql> select xingming,chengji from test where chengji>=60 order by chengji desc;
多条件的排序
mysql> select * from test order by nianling desc,chengji desc;
(2)按多字段排序

按照年龄

MYSQL高级用法 mysql高级查询语句总结_mysql

2,按结果进行分组

(1)group by 分组
  • 使用GROUP BY 语句来实现分组
  • 通常结合聚合函数一起使用
  • 可以按一个或多个字段对结果进行分组
  • group by 的语法结构
    例如·:
select column_name,aggregate_function(column_name) from table_name where column_name operator value GROUP BY column_name;

mysql> select count(xingming),chengji from test where chengji>=60 group by nianling;
+-----------------+---------+
| count(xingming) | chengji |
+-----------------+---------+
|               1 | 60      |
|               2 | 70      |
|               1 | 80      |
+-----------------+---------+
3 rows in set (0.01 sec)

mysql> select count(xingming),chengji from test where chengji>=50 group by nianling order by count(xingming) desc;
+-----------------+---------+
| count(xingming) | chengji |
+-----------------+---------+
|               2 | 70      |
|               2 | 60      |
|               1 | 80      |
+-----------------+---------+
3 rows in set (0.00 sec)
(2)group by 结合order by

3,限制结果条目

  • 只返回select查询结果的第一行做着前几行
  • 使用Limit语句限制条目
  • Limit语法结构
    例如:
select column1,column2,... from table_name [offset,] number;

mysql> select * from test;
+--------+----------+----------+---------+
| xuehao | nianling | xingming | chengji |
+--------+----------+----------+---------+
| 201001 |       17 | zhangsan | 60      |
| 201002 |       18 | lisi     | 70      |
| 201003 |       19 | wangwu   | 80      |
| 201004 |       18 | zhaoliu  | 88      |
| 201005 |       17 | lilei    | 55      |
| 201006 |       18 | lili     | 90      |
+--------+----------+----------+---------+
6 rows in set (0.00 sec)

前三个
mysql> select * from test limit 3;
+--------+----------+----------+---------+
| xuehao | nianling | xingming | chengji |
+--------+----------+----------+---------+
| 201001 |       17 | zhangsan | 60      |
| 201002 |       18 | lisi     | 70      |
| 201003 |       19 | wangwu   | 80      |
+--------+----------+----------+---------+
3 rows in set (0.00 sec)

第一个数字:位置偏移量是从零开始,第二个数字:返回记录行的最大数目
第三到第五
mysql> select * from test limit 2,3;
+--------+----------+----------+---------+
| xuehao | nianling | xingming | chengji |
+--------+----------+----------+---------+
| 201003 |       19 | wangwu   | 80      |
| 201004 |       18 | zhaoliu  | 88      |
| 201005 |       17 | lilei    | 55      |
+--------+----------+----------+---------+
3 rows in set (0.00 sec)

二,MYSQL存储过程

1, 通配符

  • 通配符%的用法
  • 用于替换字符串中的部分字符
  • 通常配合LIKE一起使用,并协同WHERE完成查询
  • 常用通配符
    %表示零个,一个或多个, _表示单个字符
    例如:
mysql> select xingming,chengji from test where xingming like '%n';
+----------+---------+
| xingming | chengji |
+----------+---------+
| zhangsan | 60      |
+----------+---------+
1 row in set (0.00 sec)

mysql> select * from test where xingming like 'z%';
mysql> select * from test where xingming like 'zhang_an';
mysql> select * from test where xingming like 'l_s_';

两者结合
mysql> select * from test where xingming like '%sa_';

2,子查询

  • 也称作内查询或者嵌套查询
  • 先主查询被执行,其结果将作为外层主查询的条件
  • 在增删改查中都可以使用子查询
  • 支持多层嵌套
  • IN语句是用来判断某个值是否在给定的结果集中
    用法:
mysql> select xuehao as 学号,xingming as 姓名,chengji as 成绩 from test where chengji in (select chengji from test where chengji>=60);
+--------+----------+--------+
| 学号   | 姓名     | 成绩   |
+--------+----------+--------+
| 201001 | zhangsan | 60     |
| 201002 | lisi     | 70     |
| 201003 | wangwu   | 80     |
| 201004 | zhaoliu  | 88     |
| 201006 | lili     | 90     |
+--------+----------+--------+
5 rows in set (0.00 sec)
降序:
mysql> select xuehao as 学号,xingming as 姓名,chengji as 成绩 from test where chengji in (select chengji from test where chengji>=60 ) order by chengji desc;

mysql> create table source as select * from test;
mysql> delete from source;
mysql> select * from source;
Empty set (0.00 sec)

mysql> insert into source select * from test where chengji in (select chengji from test where chengji>=80);
mysql> select * from source;
+--------+----------+----------+---------+
| xuehao | nianling | xingming | chengji |
+--------+----------+----------+---------+
| 201003 |       19 | wangwu   | 80      |
| 201004 |       18 | zhaoliu  | 88      |
| 201006 |       18 | lili     | 90      |
+--------+----------+----------+---------+
3 rows in set (0.00 sec)

修改:
mysql> alter table source add column num int(3);	#添加一列num
mysql> desc source;			#查表的结构
mysql> update source set num=101 where chengji in (select chengji from test where chengji >=80);
mysql> select * from source;
+--------+----------+----------+---------+------+
| xuehao | nianling | xingming | chengji | num  |
+--------+----------+----------+---------+------+
| 201003 |       19 | wangwu   |      80 |  101 |
| 201004 |       18 | zhaoliu  |      88 |  101 |
| 201006 |       18 | lili     |      90 |  101 |
+--------+----------+----------+---------+------+
3 rows in set (0.00 sec)

mysql> select * from (select * from test where chengji>=75)as a;
mysql> select * from (select * from test where chengji>=75)a;
mysql> select * from (select * from test where chengji>=75)a order by chengji desc;
mysql> delete from test where chengji in(select chengji from (select * from test where chengji >=75)a);
mysql> select * from test;
+--------+----------+----------+---------+
| xuehao | nianling | xingming | chengji |
+--------+----------+----------+---------+
| 201001 |       17 | zhangsan |      60 |
| 201002 |       18 | lisi     |      70 |
| 201005 |       17 | tianqi   |      55 |
+--------+----------+----------+---------+
3 rows in set (0.00 sec)

mysql> insert into source values(201008,18,'zhangsan',89,102);
后面条件为真则执行前面的
mysql> select count(num) from source where exists(select num from source where xingming='zhangsan');

###子查询的用法

3,NULL值

  • 表示缺失的值
  • 与数字0或者空白是不同的
  • 使用IS NULL或IS NOT NULL进行判断
  • NULL值和空值的区别
  • 空值长度为0,不占空间,NULL值的长度为NULL,占用空间
  • IS NULL无法判断空值
  • 控制使用“=”或者“<>”来处理
  • COUNT()计算时,NULL会忽略,空值会加入计算
插入空值
mysql> alter table chengji add column class varchar(25);
mysql> select * from chengji;
mysql> insert into chengji values(6,20,'liuliu',83,null,3);
mysql> select * from chengji;
+----+-----+----------+--------+------+-------+
| id | age | name     | scrore | num  | class |
+----+-----+----------+--------+------+-------+
|  1 |  17 | zhangsan |   60.0 | NULL | NULL  |
|  2 |  18 | lisi     |   70.0 | NULL | NULL  |
|  3 |  18 | wangwu   |   80.0 | NULL | NULL  |
|  4 |  17 | zhaoliu  |   95.0 | NULL | NULL  |
|  5 |  19 | tianqi   |   55.0 | NULL | NULL  |
|  6 |  20 | liuliu   |   83.0 | NULL | 3     |
+----+-----+----------+--------+------+-------+
6 rows in set (0.00 sec)

null用法
mysql> select * from chengji where class is null;
+----+-----+----------+--------+------+-------+
| id | age | name     | scrore | num  | class |
+----+-----+----------+--------+------+-------+
|  1 |  17 | zhangsan |   60.0 | NULL | NULL  |
|  2 |  18 | lisi     |   70.0 | NULL | NULL  |
|  3 |  18 | wangwu   |   80.0 | NULL | NULL  |
|  4 |  17 | zhaoliu  |   95.0 | NULL | NULL  |
|  5 |  19 | tianqi   |   55.0 | NULL | NULL  |
+----+-----+----------+--------+------+-------+
5 rows in set (0.01 sec)

mysql> select * from chengji where class is not null;
+----+-----+--------+--------+------+-------+
| id | age | name   | scrore | num  | class |
+----+-----+--------+--------+------+-------+
|  6 |  20 | liuliu |   83.0 | NULL | 3     |
+----+-----+--------+--------+------+-------+
1 row in set (0.00 sec)

4,正则表达式

  • 根据指定的匹配模式匹配记录中符合要求的特殊字符
  • 使用regexp关键字指定匹配模式
  • 常用匹配模式
  • ^匹配开始字符
  • ¥匹配结束字符
  • . 匹配任意单个字符
  • *匹配任意个前面字符
  • +匹配前面字符至少一次
  • pi|p2 匹配p1或p2

内连接:找两个表中的公共部分
外连接:分为左连接和右连接

mysql> select * from test where xingming regexp '^z';		以什么开头
mysql> select * from test where xingming regexp 'i$';		以什么结尾
mysql> select * from test where xingming regexp 'zha';		
mysql> select * from test where xingming regexp 'zha.gsan';	匹配单个字符
mysql> select * from test where xingming regexp '^[z|l]';	以z或l开头
mysql> select * from test where xingming regexp '^[^z|l]';	不以z或l开头
mysql> select * from test where xingming regexp 'e{3,5}';
mysql> select * from test where xingming regexp 'ee*';
mysql> select * from test where xingming regexp '^[d-f]';

5,连接查询

mysql> create table chengji(id int(3) not null primary key auto_increment,age int(3) not null,name varchar(64) not null,scrore decimal(4,1));
mysql> insert into chengji(age,name,scrore) values(17,'zhangsan',60),(18,'lisi',70),(18,'wangwu',80),(17,'zhaoliu',95),(19,'tianqi',55);
mysql> select * from chengji;
+----+-----+----------+--------+
| id | age | name     | scrore |
+----+-----+----------+--------+
|  1 |  17 | zhangsan |   60.0 |
|  2 |  18 | lisi     |   70.0 |
|  3 |  18 | wangwu   |   80.0 |
|  4 |  17 | zhaoliu  |   95.0 |
|  5 |  19 | tianqi   |   55.0 |
+----+-----+----------+--------+
5 rows in set (0.00 sec)

mysql> create table sushe(id int(3) not null primary key,num int(3) not null);
mysql> insert into sushe values(1,305),(2,306),(3,307),(8,308),(9,309),(10,310);
mysql> select * from sushe;
+----+-----+
| id | num |
+----+-----+
|  1 | 305 |
|  2 | 306 |
|  3 | 307 |
|  8 | 308 |
|  9 | 309 |
| 10 | 310 |
+----+-----+
6 rows in set (0.00 sec)

内连接
mysql> select * from chengji c inner join sushe s on c.id=s.id;
+----+-----+----------+--------+----+-----+
| id | age | name     | scrore | id | num |
+----+-----+----------+--------+----+-----+
|  1 |  17 | zhangsan |   60.0 |  1 | 305 |
|  2 |  18 | lisi     |   70.0 |  2 | 306 |
|  3 |  18 | wangwu   |   80.0 |  3 | 307 |
+----+-----+----------+--------+----+-----+
3 rows in set (0.00 sec)

左连接
mysql> select * from chengji c left join sushe s on c.id=s.id;
+----+-----+----------+--------+------+------+
| id | age | name     | scrore | id   | num  |
+----+-----+----------+--------+------+------+
|  1 |  17 | zhangsan |   60.0 |    1 |  305 |
|  2 |  18 | lisi     |   70.0 |    2 |  306 |
|  3 |  18 | wangwu   |   80.0 |    3 |  307 |
|  4 |  17 | zhaoliu  |   95.0 | NULL | NULL |
|  5 |  19 | tianqi   |   55.0 | NULL | NULL |
+----+-----+----------+--------+------+------+
5 rows in set (0.00 sec)

右连接
mysql> select * from chengji c right join sushe s on c.id=s.id;
+------+------+----------+--------+----+-----+
| id   | age  | name     | scrore | id | num |
+------+------+----------+--------+----+-----+
|    1 |   17 | zhangsan |   60.0 |  1 | 305 |
|    2 |   18 | lisi     |   70.0 |  2 | 306 |
|    3 |   18 | wangwu   |   80.0 |  3 | 307 |
| NULL | NULL | NULL     |   NULL |  8 | 308 |
| NULL | NULL | NULL     |   NULL |  9 | 309 |
| NULL | NULL | NULL     |   NULL | 10 | 310 |
+------+------+----------+--------+----+-----+
6 rows in set (0.00 sec)

6,字符串函数

  • 常用的字符串函数
  • 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反转

三,存储过程简介

  • 简介
  • 是一组为了完成特定功能的SQL语句集合
  • 比传统SQL速度更快,执行效率更高
  • 存储过程的优点
  • 执行一次后,会将生成的二进制代码驻留缓冲区,提高执行效率
  • SQL语句加上控制语句的集合,灵活性高
  • 在服务器端存储,客户端调用,降低网络负载
  • 可多次重复被调用,可随时修改,不影响客户端调用
  • 可完成所有数据库操作,也可控制数据库的信息访问权限
  • 创建存储过程
  • 使用CREATE PROCEDURE语句创建存储过程
  • 创建存储过程的语法结构
  • CREATE PROCEDURE <过程名> (过程参数[…])<过程体> [过程参数[…]] 格式 [IN|OUT|INOUT] <参数名> <类型>
  • 参数分为
  • 输入参数:IN
  • 输出参数:OUT
  • 输入/输出参数:INOUT
  • 存储过程的主体部分,被称为过程体
  • .以BEGIN开始,以END结束,若只有一条SQL语句
  • 以DELIMITER开始和结束

1,创建存储过程

  • 存储过程的主体部分,被称为过程体
  • 以begin开始,以end结束,若只有一条SQL语句,则可以省略begin-end
  • 以delimiter开始和结束
mysql> delimiter $$
mysql> create procedure a()
    -> begin
    -> select * from chengji limit 3;
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call a();
+----+-----+----------+--------+------+
| id | age | name     | scrore | num  |
+----+-----+----------+--------+------+
|  1 |  17 | zhangsan |   60.0 | NULL |
|  2 |  18 | lisi     |   70.0 | NULL |
|  3 |  18 | wangwu   |   80.0 | NULL |
+----+-----+----------+--------+------+
3 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
  • 不带参数的存储过程
mysql> delimiter $$
mysql> create procedure p(in num1 int,out num2 int,inout num3 int)
    -> begin
    -> select num1,num2,num3;
    -> set num1=10,num2=20,num3=30;
    -> select num1,num2,num3;
    -> end $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call p(@num1,@num2,@num3);
+------+------+------+
| num1 | num2 | num3 |
+------+------+------+
|    1 | NULL |    3 |
+------+------+------+
1 row in set (0.00 sec)

+------+------+------+
| num1 | num2 | num3 |
+------+------+------+
|   10 |   20 |   30 |
+------+------+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
in和inout参数会将全局变量的值传入存储过程中,而out参数不会将全局变量的值传入存储过程中,在全局过程使用中,参数值in、out、inout都会发生改变


mysql> select @num1,@num2,@num3;
+-------+-------+-------+
| @num1 | @num2 | @num3 |
+-------+-------+-------+
|     1 |    20 |    30 |
+-------+-------+-------+
1 row in set (0.00 sec)
调用完存储过程后,发现in参数不会对全局变量的值引起变化,而out和inout参数调用完存储过程后,会对全局变量的值产生变化,会将存储过程引用后的值赋值给全局变量,in参数赋值类型可以是变量还有定值,而out和inout参数赋值类型必须是变量

2, 删除存储过程

1、删除存储过程的语法
	DROP { PROCEDURE | FUNCTION } [ IF EXISTS ] <过程名>
2、删除的过程
mysql> drop procedure a;
mysql> call a();
ERROR 1305 (42000): PROCEDURE score.a does not exist

3,修改存储过程

1、存储过程的修改分为特征修改和内容修改
2、特征修改的方法
	ALTER PROCEDURE <过程名> [<特征>...]
3、内容修改可先删除原有存储过程,之后再创建方法