MySQL数据库高级SQL语句(四)

准备工作

create table RANK(name char(10),score char(3));
insert into RANK values('wangda',70);
insert into RANK values('xiaoer',65);
insert into RANK values('zhangsan',85);
insert into RANK values('lisi',95);
insert into RANK values('chenwu',99);
insert into RANK values('zhaoliu',75);
select * from RANK;

在这里插入图片描述

算排名

表格自我连结(Self Join),然后将结果依序列出,算出每一行之前(包含那一行本身)有多少行数

select A1.name,A1.score,count(A2.score) rank from RANK A1,RANK A2 where A1.score < A2.score OR (A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc;

在这里插入图片描述

A1,A2没有固定值,可以为任一score值,rank为别名
当A1的score字段值小于A2的score字段值、或者A1与A2的score字段值相等并且name字段值相等时,从表中查询A1的name字段值与score字段值和A2的score字段的非空值,并对A1的score字段降序排序
即比较各行的score值,若score值最大,那么排名为0+1(还有那一行本身)
若score值第二,比它大的值有1个,那么排名为1+1
若score值第三,比它大的值为2个,那么排名为2+1
… …以此类推

当A1.score的值为99时,A2.score可为99,则 count(A2.score)为1
当A1.score的值为95时,A2.score可为99、95,则 count(A2.score)为2
当A1.score的值为85时,A2.score可为99、95、85,则 count(A2.score)为3
当A1.score的值为75时,A2.score可为99、95、85、75,则 count(A2.score)为4
当A1.score的值为70时,A2.score可为99、95、85、75、70,则 count(A2.score)为5
当A1.score的值为65时,A2.score可为99、95、85、75、70、65,则 count(A2.score)为6

算中位数

select * from (select A1.name,A1.score,count(A2.score) rank from RANK A1,RANK A2 where A1.score < A2.score OR (A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc) A3 where A3.rank = (select (count(*)+1) DIV 2 from RANK);

select score RANK from (select A1.name,A1.score,count(A2.score) rank from RANK A1,RANK A2 where A1.score < A2.score OR (A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc) A3 where A3.rank = (select (count(*)+1) DIV 2 from RANK);

在这里插入图片描述

算累积总计

表格自我连结(Self Join),然后将结果依序列出,算出每一行之前(包含那一行本身)的总合

select A1.*,sum(A2.score) sum_socore from RANK A1,RANK A2 where A1.score < A2.score or(A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc;

在这里插入图片描述

算总合百分比

select A1.*,A1.score/(select sum(score) from RANK) z_sum from RANK A1,RANK A2 where A1.score < A2.score or (A1.score=A2.score and A1.name=A2.name) group by A1.name;

在这里插入图片描述

select sum(score) from RANK这一段子查询是用来算出总合
总合算出后,我们就能够将每一行一一除以总合来求出每一行的总合百分比

算累积总合百分比

select A1.name,A1.score,sum(A2.score),sum(A2.score)/(select sum(score) from RANK) Z from RANK A1,RANK A2 where A1.score < A2.score or (A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc;

select A1.name,A1.score,sum(A2.score),truncate(sum(A2.score)/(select sum(score) from RANK),2) ||'%' Z from RANK A1,RANK A2 where A1.score < A2.score or (A1.score=A2.score and A1.name=A2.name) group by A1.name order by A1.score desc;

在这里插入图片描述

用累积总计sum(A2.score)除以总合来求出每一行的累积总合百分比

空值(NULL)和无值(’’)的区别

无值的长度为0,不占用空间的;而 NULL值的长度是 NULL,是占用空间的。
IS NULL或者 IS NOT NULL,是用来判断字段是不是为 NULL 或者不是 NULL,不能查出是不是空值的。
无值的判断使用=’‘或者<>’'来处理。<>代表不等于。
在通过 count()指定字段统计有多少行数时,如果遇到 NULL值会自动忽略掉,遇到空值会加入到记录中进行计算。

create table CITY (city varchar(20));
insert into CITY values('shanghai');
insert into CITY values('beijing');
insert into CITY values('');
insert into CITY values('taijin');
insert into CITY values();
insert into CITY values('');
select * from CITY;	

在这里插入图片描述

select length(city) from CITY;
select * from CITY where city is NULL;
select * from CITY where city is not NULL;
select * from CITY where city ='';
select * from CITY where city <> '';

在这里插入图片描述
在这里插入图片描述

正则表达式

匹配模式 描述 实例
^ 匹配文本的开始字符 '^bd’匹配以 bd开头的字符串
$ 匹配文本的结束字符 'qn$'匹配以qn结尾的字符串
. 匹配任何单个字符 's.t’匹配任何s和t之间有一个字符的字符串
* 匹配零个或多个在它前面的宁字符 'fo*t’匹配 t前面有任意个o
+ 匹配前面的字符l次或多次 'hom+’匹配以 ho开头,后面至少一个m的字符串
字符串 匹配包含指定的字符串 'clo’匹配含有clo 的字符串
pl p2 匹配 pl 或 p2
[…] 匹配字符集合中的任意一个字符 '[abc]’匹配a或者b或者c
[^…] 匹配不在括号中的任何字符 '[^ab]’匹配不包含a或者b的字符串
{n} 匹配前面的字符串n 次 'g{2}’匹配含有2个g的字符串
{n,m} 匹配前面的字符串至少n 次,至多m次 'f{1,3}'匹配 f 最少 1 次,最多 3 次

语法:SELECT “栏位” FROM “表名” WHERE “栏位” REGEXP {模式};

select * from city where Store_Name regexp '^[h]';
select * from city where Store_Name regexp '[i]';
select * from city where Store_Name regexp 'hai|jin'

在这里插入图片描述

存储过程

存储过程是一组为了完成特定功能的SQL语句集合。

存储过程在使用过程中是将常用或者复杂的工作预先使用SQL语句写好并用一个指定的名称存储起来,这个过程经编译和优化后存储在数据库服务器中。
当需要使用该存储过程时,只需要调用它即可。存储过程在执行上比传统SQL速度更快、执行效率更高。

存储过程的优点:

  • 执行一次后,会将生成的二进制代码驻留缓冲区,提高执行效率
  • SQL语句加上控制语句的集合,灵活性高
  • 在服务器端存储,客户端调用时,降低网络负教
  • 可多次重复被调用,可随时修改,不影响客户端调用
  • 可完成所有的数据库操作,也可控制数据库的信息访问权限

创建存储过程

DELIMITER $$                   #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
CREATE PROCEDURE Proc ()       #创建存储过程,过程名为Proc,不带参数
-> BEGIN                       #过程体以关键字BEGIN开始
-> select * from tickets;      #过程体语句
-> END $$                      #过程体以关键字END结束
DELIMITER ;                    #将语句的结束符号恢复为分号

CALL Proc;                     #调用存储过程

在这里插入图片描述
查看存储过程

show create procedure test.Proc;
show create procedure Proc;
show procedure status like '%Proc%'\G;

在这里插入图片描述
删除除存储过程

存储过程内容的修改方法是通过删除原有存储过程,之后再以相同的名称创建新的存储过程。
drop procedure if exists Proc; #仅当存在时删除,如果指定的过程不存在,则产生一个错误
在这里插入图片描述

存储过程的控制语句

create table t (id int(10));
insert into t values(10);

存储过程的参数
IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
例:

DELIMITER $$
CREATE PROCEDURE EE(IN place char(20))
BEGIN
select * from city where Store_Name=place;
END$$

DELIMITER ;
CALL EE('beijing');

在这里插入图片描述

存储过程的条件语句if

例:

DELIMITER $$
CREATE PROCEDURE TEST1(IN num int(10))
BEGIN
declare var int;
set var=num*2;
if var>=10 then
	update tickets set Sales=Sales+1;
else 
	update tickets set Sales=Sales-1;
end if;
END $$
DELIMITER ;

在这里插入图片描述

CALL TEST1(5);
CALL TEST1(4);

在这里插入图片描述

存储过程的循环语句while

create table test(id int);

DELIMITER !!
CREATE PROCEDURE TEST2()
BEGIN
declare var int;
set var=3;
while var<5 do
	insert into test values(var);
	set var=var+1;
end while;
END!!

DELIMITER ;
CALL TEST2;
select * from test;

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_51613313/article/details/114035674