数据库
首页 > 数据库> > mysql高级查询语句3

mysql高级查询语句3

作者:互联网

sql 高级查询语句3

一计算排名,中位数,累加总值,占比百分比

1.1 算 排名

表格自我连接(self join),依次比较比自己大(或者小)以及和各个表字段值一样的,一共有几个个

然后将结果依序列出,算出每一行之前(包括那一行本身)有多少行数.

select  A1.name,A1.score,count(A1.score) rank from class2  A1,class2  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;
     

+-------------+-------+------+
| name        | score | rank |
+-------------+-------+------+
| wanglei     |   100 |    1 |
| zhoujiazhen |    90 |    2 |
| houlu       |    90 |    2 |
| zhangsan    |    80 |    4 |
| lisi        |    70 |    5 |
| lirui       |    70 |    5 |
| wangwu      |    60 |    7 |
+-------------+-------+------+
7 rows in set (0.00 sec)






select  A1.name,A1.score,count(A1.score) rank from class2  A1,class2  A2
     where A1.score <A2.score or (A1.score=A2.score and A1.name>=A2.name)
     group by A1.name order by  rank  ;
     
 +-------------+-------+------+
| name        | score | rank |
+-------------+-------+------+
| wanglei     |   100 |    1 |
| houlu       |    90 |    2 |
| zhoujiazhen |    90 |    3 |
| zhangsan    |    80 |    4 |
| lirui       |    70 |    5 |
| lisi        |    70 |    6 |
| wangwu      |    60 |    7 |
+-------------+-------+------+
7 rows in set (0.00 sec)

image-20210907224338130

image-20210907225051215



1.2 计算中位数

1.2.1借助view视图,保存查询结果,再计算中位数

#先将算排名的结果保存为视图
mysql> create view V_Middle as  
    -> select A1.name,A1.score,count(A1.score) rank from class2 A1,class2 A2 
    -> where A1.score<A2.score or (A1.score=A2.score and A1.name=A2.name)
    -> group by A1.name,A1.score order by A1.score desc;
Query OK, 0 rows affected (0.00 sec)


mysql> select * from V_Middle;
+-------------+-------+------+
| name        | score | rank |
+-------------+-------+------+
| wanglei     |   100 |    1 |
| zhoujiazhen |    90 |    2 |
| houlu       |    90 |    2 |
| zhangsan    |    80 |    4 |
| lisi        |    70 |    5 |
| lirui       |    70 |    5 |
| wangwu      |    60 |    7 |
+-------------+-------+------+
7 rows in set (0.00 sec)


#再根据排名结果计算中位数(中位数计算就是总数加1再除以2)
mysql> select name,score Middle from V_Middle 
    -> where rank= (select (count(*)+1) div 2 from class2);
+----------+--------+
| name     | Middle |
+----------+--------+
| zhangsan |     80 |
+----------+--------+
1 row in set (0.00 sec)

DIV是在MySQL中算出商的方式

image-20210907230642576

image-20210907230655606

image-20210907230932364



1.2.2 使用派生表计算中位数

select name,score Middle from 
   (select A1.name,A1.score,count(A1.score) rank from class2 A1,class2 A2 
       where A1.score<A2.score or (A1.score=A2.score and A1.name=A2.name)
        group by A1.name,A1.score order by A1.score desc) A3
   where A3.rank=(select (count(*)+1) div 2 from class2);
    
+----------+--------+
| name     | Middle |
+----------+--------+
| zhangsan |     80 |
+----------+--------+
  

image-20210907231641812



1.3 计算累计总值

表格自我连接(self join),然后将结果依序列出,算出每一行之前(包括那一行本身)的总和

select  A1.name,A1.score,sum(A2.score) sum,count(A2.score)  rank 
     from class2  A1,class2  A2
     where A1.score <A2.score or (A1.score=A2.score and A1.name=A2.name)
     group by A1.name order by  rank ;
 
 +-------------+-------+------+------+
| name        | score | sum  | rank |
+-------------+-------+------+------+
| wanglei     |   100 |  100 |    1 |
| houlu       |    90 |  190 |    2 |
| zhoujiazhen |    90 |  190 |    2 |
| zhangsan    |    80 |  360 |    4 |
| lirui       |    70 |  430 |    5 |
| lisi        |    70 |  430 |    5 |
| wangwu      |    60 |  560 |    7 |
+-------------+-------+------+------+
7 rows in set (0.00 sec)

image-20210907232537081



1.4 算占总百分比

select  A1.name,A1.score,
     A1.score/(select sum(score) from class2),
     count(A2.score)  rank 
     from class2  A1,class2  A2
     where A1.score <A2.score or (A1.score=A2.score and A1.name=A2.name)
     group by A1.name order by  rank ;
 
 +-------------+-------+------------------------------------------+------+
| name        | score | A1.score/(select sum(score) from class2) | rank |
+-------------+-------+------------------------------------------+------+
| wanglei     |   100 |                                   0.1786 |    1 |
| houlu       |    90 |                                   0.1607 |    2 |
| zhoujiazhen |    90 |                                   0.1607 |    2 |
| zhangsan    |    80 |                                   0.1429 |    4 |
| lisi        |    70 |                                   0.1250 |    5 |
| lirui       |    70 |                                   0.1250 |    5 |
| wangwu      |    60 |                                   0.1071 |    7 |
+-------------+-------+------------------------------------------+------+
7 rows in set (0.00 sec)



select  A1.name,A1.score, 
     round(A1.score/(select sum(score) from class2) *100,2)  ||  '%'  percent,
     count(A2.score)  rank 
     from class2  A1,class2  A2
     where A1.score <A2.score or (A1.score=A2.score and A1.name>=A2.name)
     group by A1.name order by  rank ;
    
+-------------+-------+---------+------+
| name        | score | percent | rank |
+-------------+-------+---------+------+
| wanglei     |   100 | 17.86%  |    1 |
| houlu       |    90 | 16.07%  |    2 |
| zhoujiazhen |    90 | 16.07%  |    2 |
| zhangsan    |    80 | 14.29%  |    4 |
| lisi        |    70 | 12.50%  |    5 |
| lirui       |    70 | 12.50%  |    5 |
| wangwu      |    60 | 10.71%  |    7 |
+-------------+-------+---------+------+

image-20210907234124810



1.5 计算累加值百分比

select  A1.name,A1.score, 
     round( sum(A2.score)/(select sum(score) from class2) *100,2)  ||  '%'  percent,
     count(A2.score)  rank 
     from class2  A1,class2  A2
     where A1.score <A2.score or (A1.score=A2.score and A1.name>=A2.name)
     group by A1.name order by  rank;
     
+-------------+-------+---------+------+
| name        | score | percent | rank |
+-------------+-------+---------+------+
| wanglei     |   100 | 17.86%  |    1 |
| houlu       |    90 | 33.93%  |    2 |
| zhoujiazhen |    90 | 50.00%  |    3 |
| zhangsan    |    80 | 64.29%  |    4 |
| lirui       |    70 | 76.79%  |    5 |
| lisi        |    70 | 89.29%  |    6 |
| wangwu      |    60 | 100.00% |    7 |
+-------------+-------+---------+------+

image-20210908000358838




二 存储过程

2.1 存储过程概述

2.1.1 什么是存储过程

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

2.1.1、优点

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


2.2  操作存储过程

2.2.1 创建存储过程

DELIMITER   ##               #将语句的结束符号从分号;临时改为两个$$ (可以是自定义)
CREATE PROCEDURE proc()      #创建存储过程,过程名为Proc, 不带参数
-> BEGIN                      #过程体以关键字BEGIN开始
-> SELECT * FROM test5;       #过程体语句(自己根据需求进行编写)
-> END  ##                    #过程体以关键字END结束
DELIMITER ;                   #将语句的结束符号恢复为分号



eg:
mysql> delimiter $$
mysql> create procedure proc()
    -> begin
    -> select * from school.class2;
    -> end $$
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;

image-20210908001618116



2.2.2 调用存储过程

#调用存储过程,call 存储过程名
call proc;

image-20210908001938724


2.2.3 查看存储过程

 #查看某个存储过程的具体信息(如果在指定库中,库名可以省略)
SHOW CREATE PROCEDURE [数据库.] 存储过程名;        

#查看存储过程装态
SHOW PROCEDURE STATUS [LIKE '%proc%'] \G             

image-20210908002659630



2.2.4存储过程的参数

IN输入参数

  • 表示调用者向过程传入值(传入值可以是字面量或变量)

OUT输出参数

  • 表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)

INOUT输入输出参数

  • 既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
mysql> delimiter $$
mysql> create procedure proc2(in inname char(20))
    -> begin 
    -> select * from school.class2 where name=inname;
    -> end$$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> 
mysql> call proc2('wanglei');
+---------+-------+
| name    | score |
+---------+-------+
| wanglei |   100 |
+---------+-------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

image-20210908003450115

image-20210908003601630



2.2.5 删除存储过程

#删除school库里的存储过程proc。 if exists ,仅在存在时执行,
drop  procedure  if exists school.proc;  

image-20210908004433212



2.3 存储过程的控制语句

2.3.1 条件控制语句 if-then-else ....end if

mysql> delimiter $$
mysql> create procedure proc_num(in  num int)
    -> begin
    -> declare bianliang int;         #declare ,设置变量
    -> set bianliang=num *2;
    -> if bianliang >15 then
    -> update school.num set id=id+1;
    -> else
    -> update school.num set id=id-5;
    -> end if;              #end if 结束if语句
    -> end $$
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;


#调用对等体,并传入参数
call proc_num(6)
call proc_num(10);

image-20210908005804872

image-20210908010248203



2.3.2 循环语句 while .....end while

mysql> delimiter $$
mysql> create procedure proc_num2()
    -> begin 
    -> declare bianliang int;
    -> set bianliang=0;
    -> while  bianliang<10 do
    -> update school.num set id=id+1;
    -> set  bianliang=bianliang+1;
    -> end while;        #end while 结束while 循环
    -> end $$
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

call proc_num2;

image-20210908011148732

image-20210908011344171

标签:语句,存储,name,查询,A1,score,mysql,class2
来源: https://www.cnblogs.com/zhijiyiyu/p/15240893.html