SQL复习

一、启动 mysql -hlocalhost -uroot -p

80版本sql需要修改加密形式才能用navicat连接

alter user 'root'@localhost identified with mysql _native_password by '123456';

创建数据库-创建表-新建值、主键、长度、空值

insert into (table)(主键) values (值);

二、符号:--备注;null、''空值;%任意字符串;like 模糊;as命名(可省略);in范围大于=;where 后不能搭配聚合函数,having可以; 

distinct去重;group by having 分组查询后按条件筛选;

三、语句管理

1、统计每门课程的学生选修人数(超过2人的课程才统计)
要求输出课程号和选修人数,查询结果按人数降序排序,若人数相同,按课程号升序排序
select 课程号,count(学号) as '人数' from score

group by 课程号 having (课程号) >2 order by count(学号) desc,课程号 asc;

2、查询没有学全所有课的学生的学号、姓名|

select 姓名,学号 from student where 学号 in 

(select 学号 from score group by 学号

 having count(课程号)<(select count(课程号) from course));

3、查询各学生的年龄(精确到月份)

select 学号,timestampdiff(month,出生日期,now())/12 from student 

4、-- 考察case表达式

查询出每门课程的及格人数和不及格人数

SELECT 课程号,sum(case when 成绩>=60 then 1 else 0 end) as 及格人数,

sum(case when 成绩<60 then 1 else 0 end) as 不及格人数

from score group by 课程号;

5、使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称

SELECT a.课程号,b.课程名称,

sum(case when 成绩 between 85 and 100 

then 1 else 0 end) as '[100-85]',

sum(case when 70<=成绩 and 成绩<85 

then 1 else 0 end) as '[85-70]',

sum(case when 60<=成绩 and 成绩<70

then 1 else 0 end) as '[70-60]',

sum(case when 60>成绩 then 1 else 0 end) as '[<60]'

from score as a right join course as b  on a.课程号=b.课程号 group by a.课程号,b.课程名称;

6、行列转换

select 学号, (case 课程号 when '0001' then 成绩 else 0 end) as '课程号0001',

(case 课程号 when '0002' then 成绩 else 0 end) as '课程号0002',

(case 课程号 when '0003' then 成绩 else 0 end) as '课程号0003'

from score group by 学号;

7、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select a.姓名,b.学号,avg(b.成绩)
from student a inner join score b on a.学号=b.学号
where b.成绩<60
group by a.学号 having count(b.学号)>=2;

8、复制表格
-查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
select distinct a.学号,a.成绩,a.课程号
from score a
inner join score b on a.学号=b.学号
where a.成绩=b.成绩 and a.课程号!=b.课程号;

9、查询课程编号为“0001”的课程比“0002”的课程成绩高的所有学生的学号
【知识点】多表连接+条件,思路如图
select a.学号,a.成绩
from (select 学号,成绩 from score where 课程号='0001') a
inner join (select 学号,成绩 from score where 课程号='0002') b on a.学号=b.学号
where a.成绩>b.成绩;

10、查询学过编号为“0001”的课程并且也学过编号为“0002”的课程的学生的学号、姓名
select a.学号 from
(select 学号 ,成绩 from score where 课程号=01) as a
inner join (select 学号 ,成绩 from score where 课程号=02) as b
on a.学号 =b.学号
inner join student c on c.学号 =a.学号

11、查询没学过“孟扎扎”老师课的学生的学号、姓名
select 姓名,学号
from student
where 学号 not in
(select 学号 from score b where 课程号=
(select 课程号 from course where 教师号 =
(select 教师号 from teacher where 教师姓名 = '孟扎扎')));

12、查询至少有一门课与学号为“0001”的学生所学课程相同的学生的学号和姓名

select 姓名,学号 from student where 学号 in
(select distinct(学号) from score a where a.课程号 in
(select 课程号 from score where 学号='0001')) and 学号!=0001;

13、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

select 学号,AVG(a.成绩),
max(case when b.课程名称='语文' then a.成绩 else null end) as '语文',
max(case when b.课程名称='数学' then a.成绩 else null end) as '数学',
max(case when b.课程名称='英语' then a.成绩 else null end) as '英语'
from score a inner join course b on a.课程号 = b.课程号
group by a.学号 order by AVG(a.成绩) desc;

14、窗口函数 row_number() over(....)

查询学生平均成绩及其名次
select 学号,AVG(a.成绩) as 平均成绩,
row_number() over(order by AVG(a.成绩) desc)
from score a inner join course b on a.课程号 = b.课程号
group by 学号;

按各科成绩进行排序,并显示排名
select 课程号,学号,成绩,
row_number() over (partition by 课程号 order by 成绩 desc) '排名'  from score ;

15、查询每门功成绩最好的前两名学生姓名
select b.姓名,课程号,成绩,a.排名 from(
select 课程号,学号,成绩,
row_number() over (partition by 课程号 order by 成绩 desc) '排名'
from score) a
inner join student b on a.学号=b.学号
where a.排名<3

16、分组聚合 group_concat

select product_id,branch,group_concat(t.stock order by t.stock desc) stocks

from (select * from product_stock) t group by product_id,branch;

截取最大值

substring_index(group_concat(......),',',1)

sql中的over函数和row_numbert()函数配合使用,可生成行号。可对某一列的值进行排序,对于相同值的数据行进行分组排序。

原文地址:https://www.cnblogs.com/ybxw/p/13294947.html