sql 高级查询语句3
表格自我连接(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)
#先将算排名的结果保存为视图 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中算出商的方式
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 | +----------+--------+
表格自我连接(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)
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 | +-------------+-------+---------+------+
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 | +-------------+-------+---------+------+
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 ;
#调用存储过程,call 存储过程名 call proc;
#查看某个存储过程的具体信息(如果在指定库中,库名可以省略) SHOW CREATE PROCEDURE [数据库.] 存储过程名; #查看存储过程装态 SHOW PROCEDURE STATUS [LIKE '%proc%'] \G
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)
#删除school库里的存储过程proc。 if exists ,仅在存在时执行, drop procedure if exists school.proc;
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);
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;