MySQL--关于MySQL的那些练习题

之前联系了一些MySQL的查询相关知识,现在补充作为一个记录,免得自己忘记。

致谢博主:https://blog.csdn.net/dehu_zhou/article/details/52881587

#建表语句与测试数据
--创建测试数据
create table Student(
S varchar(10),
Sname varchar(10),
Sage datetime,
Ssex nvarchar(10)
) ;
 
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
 
create table SC(
Sid varchar(10),
Cid varchar(10),
score decimal(18,1)
);
 
insert into SC values('01' , '01' , 80);
insert into SC values('01' , '02' , 90);
insert into SC values('01' , '03' , 99);
insert into SC values('02' , '01' , 70);
insert into SC values('02' , '02' , 60);
insert into SC values('02' , '03' , 80);
insert into SC values('03' , '01' , 80);
insert into SC values('03' , '02' , 80);
insert into SC values('03' , '03' , 80);
insert into SC values('04' , '01' , 50);
insert into SC values('04' , '02' , 30);
insert into SC values('04' , '03' , 20);
insert into SC values('05' , '01' , 76);
insert into SC values('05' , '02' , 87);
insert into SC values('06' , '01' , 31);
insert into SC values('06' , '03' , 34);
insert into SC values('07' , '02' , 89);
insert into SC values('07' , '03' , 98);

create table Course(
Cid varchar(10),
Cname varchar(10),
Tid varchar(10)
);
 
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');
 
create table Teacher(
Tid varchar(10),
Tname varchar(10)
);
 
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

  练习题:

    题一:查询"01"课程比"02"课程成绩高的学生的信息及课程分数。  

--分析过程:
--基表:学生的信息(Student),课程分数(SC) --条件: #1.成绩自己比自己; #2.查询学生的信息; #方法1:使用内连接,并作为子查询条件进行查询 SELECT t2.*, t1.`01分数`, t1.`02分数` FROM ( SELECT a.Sid, a.score AS '01分数', b.score AS '02分数' FROM SC a INNER JOIN SC b ON a.Sid = b.Sid and a.Cid='01' and b.Cid='02' WHERE a.score > b.score ) t1, Student t2 where t1.Sid=t2.Sid; #方法2:使用三层内连接连续使用 #考点:三层嵌套内连接 SELECT a.*, b.score AS '01分数', c.score AS '02分数' FROM Student a INNER JOIN SC b ON a.Sid = b.Sid AND b.Cid = '01' INNER JOIN SC c ON a.Sid = c.Sid AND c.Cid = '02' WHERE b.score > c.score;

    2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数

#与题目1一致,修改成绩比较条件

SELECT
	a.*, b.score AS '01分数',
	c.score AS '02分数'
FROM
	Student a
INNER JOIN SC b ON a.Sid = b.Sid
AND b.Cid = '01'
INNER JOIN SC c ON a.Sid = c.Sid
AND c.Cid = '02'
WHERE
	b.score < c.score;

    3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

#考点,group by 子句以及having的条件删选

SELECT
	a.*, b.avg_score
FROM
	Student a,
	(
		SELECT
			t.Sid,
			round(avg(t.score), 2) AS avg_score
		FROM
			SC t
		GROUP BY
			t.Sid
		HAVING
			avg(t.score) > 60
	) b
WHERE
	a.Sid = b.Sid;

#+外连接版本
SELECT
	t1.*,t2.avg_score
FROM
	(
		SELECT
			t.Sid,
			round(avg(t.score), 2) AS avg_score
		FROM
			SC t
		GROUP BY
			t.Sid
		HAVING
			avg(t.score) > 60
	) t2
LEFT JOIN Student t1 ON t2.Sid = t1.Sid;


#外连接凝练版本
SELECT
	t1.*, round(avg(t.score), 2) AS avg_score
FROM
	SC t
RIGHT JOIN Student t1 ON t.Sid = t1.Sid
GROUP BY
	t.Sid
HAVING
	avg(t.score) > 60;

    4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩

SELECT
	t1.*, round(avg(t.score), 2) AS avg_score
FROM
	SC t
RIGHT JOIN Student t1 ON t.Sid = t1.Sid
GROUP BY
	t.Sid
HAVING
	avg(t.score) < 60;

    5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩  

SELECT
	b.Sname,
	a.Sid,
	count(DISTINCT a.Cid) as '选课总数',
	sum(a.score) as '总成绩'
FROM
	SC a
LEFT JOIN Student b ON a.Sid = b.Sid
GROUP BY
	a.Sid;

    6、查询"李"姓老师的数量 

select count(*) from Teacher a where a.Tname like '李%';

    7、查询学过"张三"老师授课的同学的信息 

  

SELECT
	a.Tname,
	b.Cid,
	d.*
FROM
	Teacher a,
	Course b,
	SC c,
	Student d
WHERE
	a.Tname = '张三'
AND a.Tid = b.Tid
AND b.Cid = c.Cid
AND c.Sid = d.Sid;

#方法2:使用三层内连接连续使用
SELECT
	a.*
FROM
	Student a
INNER JOIN SC b ON a.Sid = b.Sid
INNER JOIN Course c ON b.Cid = c.Cid
INNER JOIN Teacher d ON c.Tid = d.Tid
WHERE
	d.Tname = '张三'
GROUP BY
	1,2,3,4;  #按照查询(select后面的)的1,2,3,4字段来分组


#方法3:方法2基础上补充
SELECT
	a.*
FROM
	Student a
LEFT JOIN (
	SELECT
		a.*
	FROM
		Student a
	INNER JOIN SC b ON a.Sid = b.Sid
	INNER JOIN Course c ON b.Cid = c.Cid
	INNER JOIN Teacher d ON c.Tid = d.Tid
	WHERE
		d.Tname = '张三'
	GROUP BY
		1,2,3,4
) t ON a.Sid = t.Sid
WHERE
	t.Sid IS NOT NULL;

    8、查询没学过"张三"老师授课的同学的信息 

#方法1:直接对原来学过张三老师课程的学生信息进行not in

SELECT
	*
FROM
	Student t
WHERE
	t.Sid NOT IN (
		SELECT
			d.Sid
		FROM
			Teacher a,
			Course b,
			SC c,
			Student d
		WHERE
			a.Tname = '张三'
		AND a.Tid = b.Tid
		AND b.Cid = c.Cid
		AND c.Sid = d.Sid
	);
#NOT IN 与 NOT EXISTS的用法区别
SELECT
	*
FROM
	Student t
WHERE
	 not EXISTS (
		SELECT
			*			#此处返回的是整个结果集,如果单挑sid,则返回的结果与预期结果不一致
		FROM
			Teacher a,
			Course b,
			SC c,
			Student d
		WHERE
			a.Tname = '张三'
		AND a.Tid = b.Tid
		AND b.Cid = c.Cid
		AND c.Sid = d.Sid
		AND d.Sid = t.Sid   #此处为结果集的判断
	);

  9、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

SELECT
	c.*,a.score as '01分数',b.score as '02分数'
FROM
	Student c
INNER JOIN SC a ON c.Sid = a.Sid
INNER JOIN SC b ON a.Sid = b.Sid
AND a.Cid = '01'
AND b.Cid = '02';

  10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息 

#重要,我没有做出来
##方法:连续的左连接,筛选出差异结果
SELECT
	*
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
AND b.Cid = '01'
LEFT JOIN SC c ON a.Sid = c.Sid
AND c.Cid = '02'
WHERE
	b.Cid = '01'
AND c.Cid IS NULL;

  11、查询没有学全所有课程的同学的信息 

SELECT
	*
FROM
	Student b
LEFT JOIN SC a ON a.Sid = b.Sid
GROUP BY
	a.Sid
HAVING
	count(a.cid) < 3;

#完善方法
SELECT
	a.*
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
LEFT JOIN (
	SELECT
		COUNT(1) anum
	FROM
		Course
) c ON 1 = 1  #通过子查询和恒真条件筛选
GROUP BY
	1, 2, 3, 4
HAVING
	MAX(c.anum) > COUNT(b.Cid);

    12、查询至少有一门课与学号为"01"的同学所学相同的同学的信息

SELECT DISTINCT
	b.*
FROM
	Student b
LEFT JOIN SC c ON b.Sid = c.Sid
AND c.Cid IN (
	SELECT
		a.Cid
	FROM
		SC a
	WHERE
		a.Sid = '01'
);

#方法2:
SELECT
	a.*
FROM
	Student a
INNER JOIN SC b ON a.Sid = b.Sid
WHERE
	EXISTS (
		SELECT
			1    
		FROM
			SC
		WHERE
			Sid = '01'
		AND Cid = b.Cid
	)
GROUP BY
	1, 2, 3, 4;

#方法3::通过组装cid字段比对进行筛选
#重点:GROUP_CONCAT(cid ORDER BY cid) 函数的用法
#1.需要配合group by 子句使用
#2.内部字段的排序的用法

SELECT DISTINCT
	t.*
FROM
	Student t
INNER JOIN SC t1 ON t.Sid = t1.Sid
WHERE
	t.Sid IN (
		SELECT
			t3.Sid
		FROM
			(
				SELECT
					sid,
					GROUP_CONCAT(cid ORDER BY cid) AS cid_list
				FROM
					SC a
				WHERE
					a.sid = '01'
				GROUP BY
					sid
			) t2
		RIGHT JOIN (
			SELECT
				sid,
				GROUP_CONCAT(cid ORDER BY cid) AS cid_list
			FROM
				SC a
			GROUP BY
				sid
		) t3 ON t2.cid_list = t3.cid_list
		WHERE
			t2.sid IS NOT NULL
	);

    14、查询没学过"张三"老师讲授的任一门课程的学生姓名 

SELECT
	t.*, t1.Tid
FROM
	Student t
LEFT JOIN (
	SELECT
		a.*, d.Tid
	FROM
		Student a
	LEFT JOIN SC b ON a.sid = b.sid
	LEFT JOIN Course c ON c.Cid = b.Cid
	LEFT JOIN Teacher d ON c.Tid = d.Tid
	AND d.Tname = '张三'
	WHERE
		d.Tid IS NOT NULL
) t1 ON t.Sid = t1.sid
WHERE
	t1.tid IS NULL;

    15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 

SELECT
	*
FROM
	Student t
LEFT JOIN (
	SELECT
		sid,
		round(avg(score), 1) AS avg_score
	FROM
		SC a
	WHERE
		a.score < 60
	GROUP BY
		sid
	HAVING
		count(*) > 1
) t1 ON t.Sid = t1.sid
WHERE
	t1.avg_score IS NOT NULL;
#优化
SELECT
	a.Sid       ,
	a.Sname       ,
	round(avg(score), 1) AS avg_score
FROM
	Student a
INNER JOIN SC b ON a.Sid = b.Sid
GROUP BY
	1,
	2
HAVING
	SUM(
		CASE
		WHEN b.Score >= 60 THEN
			0
		ELSE
			1
		END
	) >= 2;

    16、检索"01"课程分数小于60,按分数降序排列的学生信息

SELECT
	a.*
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
AND b.Cid = '01'
WHERE
	b.score < 60
ORDER BY
	b.Cid DESC;

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

select t.*, round((s01+s02+s03)/3,2) as avs from (
SELECT a.*
	,SUM(CASE WHEN b.Cid='01' THEN b.score ELSE 0 END) AS s01 
	,SUM(CASE WHEN b.Cid='02' THEN b.score ELSE 0 END) AS s02 
	,SUM(CASE WHEN b.Cid='03' THEN b.score ELSE 0 END) AS s03
FROM Student a
LEFT JOIN SC b
ON a.Sid=b.Sid
GROUP BY 1,2,3,4
) t ORDER BY avs desc;


select * from Student t 
LEFT JOIN (
	select a.Sid
		,max(case when a.Cid='01' THEN a.score ELSE 0 END) as s01
		,max(case when a.Cid='02' THEN a.score ELSE 0 END) as s02
		,max(case when a.Cid='03' THEN a.score ELSE 0 END) as s03
		,round(avg(case when a.score is null then 0 else a.score end),2) as avs 
	from SC a group BY a.Sid ) t1
on t.Sid = t1.Sid
;

    18、查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

#-- --及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
#考察重点再分组

select 
	a.cid,b.Cname,max(a.score),min(a.score),avg(a.score)
	,concat(ROUND(count(IF(a.score >=60 ,1,null))/count(1) * 100,2),'%') as '及格率'
	,concat(ROUND(sum(case when a.score >= 70 and a.score < 80  then 1 else 0 end)/count(1) * 100,2),'%') as '中等率'
	,concat(ROUND(sum(case when a.score >= 80 and a.score < 90 then 1 else 0 end)/count(1) * 100,2),'%') as '优良率'
	,concat(ROUND(sum(case when a.score >= 90 then 1 else 0 end)/count(1) * 100,2),'%') as '优秀率'
from SC a  
INNER JOIN Course b on a.Cid = b.Cid group by 1,2;

    19、按各科成绩进行排序,并显示排名

#单科排序方法,自定义变量
SET @rn:=0;
SELECT a.*,@rn:=@rn+1 as '排名'
FROM(
select a.*,b.score from Course a INNER JOIN SC b on a.Cid = b.Cid where a.Cid='01' ORDER BY a.Cid,b.score desc
)a ;
#按科目排序方法,通过自连接比对排序规则
SELECT
	a.*, count(b.Cid) + 1 AS tp
FROM
	SC a
LEFT JOIN SC b ON a.Cid = b.Cid
AND a.score < b.score
GROUP BY
	a.Sid,
	a.Cid
ORDER BY
	a.Cid,
	a.score DESC;

    20、查询学生的总成绩并进行排名

SET @ct := 0;
 
SELECT
	(@ct := @ct + 1) AS '排名',
	b.Sname,
	ifnull(sum(a.score), 0) AS '总成绩'
FROM
	SC a
RIGHT JOIN Student b ON a.Sid = b.Sid 
GROUP BY
	a.Sid
ORDER BY
	sum(a.score) DESC;

    21、查询不同老师所教不同课程平均分从高到低显示 

##没有统计未参考学生的平均分
select d.Tname,c.Cname,ROUND(sum(b.score)/count(a.Sid),2) as '科目平均分'
from Student a LEFT JOIN SC b on a.Sid = b.Sid 
LEFT JOIN Course c on c.Cid = b.Cid
LEFT JOIN Teacher d on c.Tid = d.Tid
where b.Cid is not null group by b.Cid  ORDER BY sum(b.score)/count(a.Sid) desc;


SELECT a.*,b.Cname,AVG(c.Score) ascore
FROM Teacher a
INNER JOIN Course b
ON a.Tid=b.Tid
INNER JOIN SC c
ON b.Cid=c.Cid
GROUP BY 1,2,3
ORDER BY ascore DESC ;
#统计未参考学生的平均分
select 
sum(case when b.cid = '01' then b.score else 0 end)/count(distinct a.Sid) as avg_01,
sum(case when b.cid = '02' then b.score else 0 end)/count(distinct a.Sid) as avg_02,
sum(case when b.cid = '03' then b.score else 0 end)/count(distinct a.Sid) as avg_03 

 from Student a LEFT JOIN SC b on a.Sid = b.Sid;

    22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩

#核心为题19按科目的成绩排序
SELECT
	c.Sname,
	d.cid,
	d.score,
	d.tp
FROM
	Student c
INNER JOIN (
	SELECT
		a.*, count(b.Cid) + 1 AS tp
	FROM
		SC a
	LEFT JOIN SC b ON a.Cid = b.Cid
	AND a.score < b.score
	GROUP BY
		a.Sid,
		a.Cid
	HAVING
		count(b.Cid) + 1 IN (2, 3)
) d ON c.Sid = d.sid;

    23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比 

select  t.*,c.Cname
,concat(round(t.bjg/sum(t.bjg+t.pt+t.lh+t.yx)* 100 ,2),'%') as bl_bjg 
,concat(round(t.pt/sum(t.bjg+t.pt+t.lh+t.yx)* 100 ,2),'%') as bl_pt
,concat(round(t.lh/sum(t.bjg+t.pt+t.lh+t.yx)* 100 ,2),'%') as bl_lh
,concat(round(t.yx/sum(t.bjg+t.pt+t.lh+t.yx)* 100 ,2),'%') as bl_yx

from (
select cid
,sum(case when a.score < 60 then 1 else 0 end) as 'bjg'
,sum(case when a.score > 60 and a.score <= 70 then 1 else 0 end) as 'pt'
,sum(case when a.score > 70 and a.score <= 80 then 1 else 0 end) as 'lh'
,sum(case when a.score > 80 then 1 else 0 end) as 'yx'
 from SC a group by a.cid ) t 
LEFT JOIN Course c  on t.cid =c.cid
GROUP BY t.cid 
;

#直接计算
SELECT a.Cid
       ,a.cname
       ,SUM(CASE WHEN b.score<=100 AND b.score>85 THEN 1 ELSE 0 END) AS 'yx'
       ,SUM(CASE WHEN b.score<=85  AND b.score>70 THEN 1 ELSE 0 END) AS 'lh'
       ,SUM(CASE WHEN b.score<=70  AND b.score>60 THEN 1 ELSE 0 END) AS 'jg'
       ,SUM(CASE WHEN b.score<=60  AND b.score>0 THEN 1 ELSE 0 END) AS 'bjg'   
       ,SUM(CASE WHEN b.score<=100 AND b.score>85 THEN 1 ELSE 0 END)/COUNT(1) AS 'yx%'
       ,SUM(CASE WHEN b.score<=85  AND b.score>70 THEN 1 ELSE 0 END)/COUNT(1) AS 'lh%'
       ,SUM(CASE WHEN b.score<=70  AND b.score>60 THEN 1 ELSE 0 END)/COUNT(1) AS 'jg%'
       ,SUM(CASE WHEN b.score<=60  AND b.score>0 THEN 1 ELSE 0 END)/COUNT(1) AS 'bjg%'
FROM Course a
INNER JOIN SC b
ON a.Cid=b.Cid
GROUP BY 1,2 ;

    24、查询学生平均成绩及其名次 

set @mc := 0;
select t.* ,@mc := @mc + 1 as '名次' from (
select c.Sid,c.Sname,sum(b.score)/3 as pjf  from Course a LEFT JOIN SC b on a.Cid = b.Cid 
RIGHT JOIN Student c on b.Sid =c.Sid group by b.Sid ORDER BY pjf desc ) t ;


#方法2
SELECT a.*
    ,COUNT(b.Sid)+1
FROM (
    SELECT a.*,AVG(CASE WHEN b.SCore IS NULL THEN 0 ELSE b.SCore END) AS aSCore
    FROM Student a
    LEFT JOIN SC b
    ON a.Sid=b.Sid
    GROUP BY 1,2,3,4
     )a
LEFT JOIN(
    SELECT a.*,AVG(CASE WHEN b.SCore IS NULL THEN 0 ELSE b.SCore END) AS aSCore
    FROM Student a
    LEFT JOIN SC b
    ON a.Sid=b.Sid
    GROUP BY 1,2,3,4
     )b
ON a.aSCore<b.aSCore
GROUP BY 1,2,3,4,5 ;

    25、查询各科成绩前三名的记录

##题22 方法的同种类型

SELECT
	c.Sname,
	d.cid,
	d.score,
	d.tp
FROM
	Student c
INNER JOIN (
	SELECT
		a.*, count(b.Cid) + 1 AS tp
	FROM
		SC a
	LEFT JOIN SC b ON a.Cid = b.Cid
	AND a.score < b.score
	GROUP BY
		a.Sid,
		a.Cid
	HAVING
		count(b.Cid) + 1 <4
) d ON c.Sid = d.sid order by d.cid;


SELECT a.*,COUNT(b.cid)+1 AS ascore
FROM SC a
LEFT JOIN SC b
ON a.cid=b.cid AND a.score<b.score
GROUP BY 1,2,3
HAVING ascore<=3
ORDER BY a.cid,ascore ;

    26查询每门课程被选修的学生数 

SELECT a.* ,COUNT(b.sid)
FROM Course a
LEFT JOIN SC b
ON a.cid=b.cid
GROUP BY 1,2,3 ;

    27、查询出只有两门课程的全部学生的学号和姓名  

SELECT
	a.*
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
GROUP BY
	b.Sid
HAVING
	count(b.cid) = 2;

    28、查询男生、女生人数 

SELECT
	a.Ssex,
	count(a.Sid)
FROM
	Student a
GROUP BY
	a.Ssex;  

#29、查询名字中含有"风"字的学生信息 select * from Student a where a.Sname like '%风%';
#30、查询同名同性学生名单,并统计同名人数 select * from Student a group by a.Sname HAVING count(a.Sname)>1; #31、查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime) SELECT * FROM Student WHERE YEAR(sage)=1990 ;

    #32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号

SELECT a.*,AVG(b.Score) as ore
FROM Course a
LEFT JOIN SC b
ON a.cid=b.cid
GROUP BY 1,2,3
ORDER BY  ore DESC,a.cid ;

    33、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩 

SELECT
	a.Sid,
	a.Sname,
	sum(
		CASE
		WHEN b.score IS NULL THEN
			0
		ELSE
			b.score
		END
	) / 3 AS avgsc
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
GROUP BY
	a.Sid
HAVING
	avgsc > 85;

    34、查询课程名称为"数学",且分数低于60的学生姓名和分数 

SELECT
	a.*, b.score
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.sid
LEFT JOIN Course c ON b.Cid = c.Cid
WHERE
	 b.score  < 60
AND c.Cname = '数学' or c.Cname is null;

    35、查询所有学生的课程及分数情况; 

SELECT
	c.cname,a.*,b.score
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
LEFT JOIN Course c on b.Cid = c.Cid
ORDER BY
	c.cname,
	a.Sid,
	b.Cid;

    36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数;

SELECT DISTINCT
	b.Sname,
	c.Cname,
	a.score
FROM
	Student b
LEFT JOIN SC a ON a.Sid = b.Sid
LEFT JOIN Course c ON c.Cid = a.Cid
WHERE
	a.score > 70;

    #37 不及格的

SELECT DISTINCT
	b.Sname,
	c.Cname,
	a.score
FROM
	Student b
LEFT JOIN SC a ON a.Sid = b.Sid
LEFT JOIN Course c ON c.Cid = a.Cid
WHERE
	a.score < 60 or a.score is null;

    #38查询课程编号为01且课程成绩在80分以上的学生的学号和姓名;

SELECT DISTINCT
	b.Sname,
	c.Cname,
	a.score
FROM
	Student b
LEFT JOIN SC a ON a.Sid = b.Sid
LEFT JOIN Course c ON c.Cid = a.Cid
WHERE
	a.score > 80 and a.Cid='01';

    39、求每门课程的学生人数 

SELECT
	a.Cid,
	count(a.Sid)
FROM
	SC a
GROUP BY
	a.Cid;

    40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩

#方法1:排序获取结果
SELECT
	*
FROM
	Student a
LEFT JOIN SC b ON a.Sid = b.Sid
LEFT JOIN Course c ON b.Cid = c.Cid
LEFT JOIN Teacher d ON c.Tid = d.Tid
WHERE
	d.Tname = '张三'
ORDER BY
	b.score DESC
LIMIT 1;

#方法2: 通过内连接最大值匹配
SELECT a.*,b.score
FROM Student a
INNER JOIN SC b
ON a.Sid=b.Sid
INNER JOIN(
    SELECT c.Cid ,MAX(c.score) AS maxscore FROM Teacher a
    INNER JOIN Course b
    ON a.Tid=b.Tid
    INNER JOIN SC c
    ON b.Cid=c.Cid
    WHERE a.Tname='张三'
    GROUP BY c.Cid )c
ON b.Cid=c.Cid AND b.score=c.maxscore ;

    41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 

SELECT DISTINCT
	c.Sname,
	c.Sid,
	a.Cid,
	d.cname,
	a.score
FROM
	Student c
LEFT JOIN SC a ON a.Sid = c.Sid
INNER JOIN SC b ON a.sid = b.Sid
LEFT JOIN Course d ON a.Cid = d.Cid
WHERE
	a.Cid != b.Cid
AND a.score = b.score;

#方法2
SELECT a.sid
    ,a.cid
    ,a.SCore
FROM SC a
INNER JOIN (
    SELECT a.SCore
        ,b.sid
        ,COUNT(1)
    FROM SC a
    INNER JOIN Student b
    ON a.sid=b.sid
    GROUP BY a.SCore,b.sid
    HAVING COUNT(1)>1
)b
ON a.sid=b.sid AND a.SCore=b.SCore ;

    42、查询每门功成绩最好的前两名 ,同22

SELECT
	c.Sname,
	d.cid,
	d.score,
	d.tp
FROM
	Student c
INNER JOIN (
	SELECT
		a.*, count(b.Cid) + 1 AS tp
	FROM
		SC a
	LEFT JOIN SC b ON a.Cid = b.Cid
	AND a.score < b.score
	GROUP BY
		a.Sid,
		a.Cid
	HAVING
		count(b.Cid) + 1 <3
) d ON c.Sid = d.sid order by d.cid; 

    43、统计每门课程的学生选修人数(超过5人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列  

SELECT
	a.Cid,
	a.Cname,
	count(b.Sid)
FROM
	Course a
LEFT JOIN SC b ON a.Cid = b.Cid
GROUP BY
	b.Cid
HAVING
	count(b.Sid) > 5
ORDER BY
	count(b.Sid) DESC,
	b.Cid;

    

    

#方法3::通过组装cid字段比对进行筛选#重点:GROUP_CONCAT(cid ORDER BY cid) 函数的用法#1.需要配合group by 子句使用#2.内部字段的排序的用法
SELECT DISTINCTt.*FROMStudent tINNER JOIN SC t1 ON t.Sid = t1.SidWHEREt.Sid IN (SELECTt3.SidFROM(SELECTsid,GROUP_CONCAT(cid ORDER BY cid) AS cid_listFROMSC aWHEREa.sid = '01'GROUP BYsid) t2RIGHT JOIN (SELECTsid,GROUP_CONCAT(cid ORDER BY cid) AS cid_listFROMSC aGROUP BYsid) t3 ON t2.cid_list = t3.cid_listWHEREt2.sid IS NOT NULL);

猜你喜欢

转载自www.cnblogs.com/wyf-349/p/11814051.html