下面分享关于SQL的题目,包括数据库和答案解析。希望对大家有帮助。
这属于基础题型,大家可以用于日常练习,虽然是基础题,但里面所以知识点都概括了。如果你能够全部理解透彻,真的,这你自己本身是能够感受到的一个提升,很大的提升。
(答案里面忽略大小写,建议大家在写SQL语句是时候,统一使用大写,如果喜欢小写,也可以,不过,最好统一大写或小写)
答案不唯一,下面是纯属个人思路,如果有更好的想法可以安排上,SQL可以有多种解题方法,不同的思路不同的做法。
先放上数据库,大家运行的时候,记得需要导入数据库。
-- 学生表 Student
create table Student(Sid varchar(6), Sname varchar(10), Sage datetime, Ssex varchar(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' , '女');
-- 成绩表 SC
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);
-- 课程表 Course
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');
-- 教师表 Teacher
create table Teacher(Tid varchar(10),Tname varchar(10));
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
题目与答案:
1. 查询课程编号“02”的成绩比课程编号“01”课程低的所有同学的学号、姓名
分析:使用自连接
select s.Sid,c.Sname from SC s
left join Student c on c.Sid=s.Sid
where s.score >= (
select s2.score from sc s2
where s.Sid = s2.Sid and s2.Cid = '02'
)
and s.Cid = '01'
2.列出每个学生的学生编号、姓名、课程名、授课老师姓名(没课程的学生不用列出)
分析:使用join on连接三个表相关联
SELECT
s.Sid,
s.Sname,
c.Cid,
c.Cname,
t.Tname
FROM
sc
JOIN student AS s ON sc.Sid = s.Sid
JOIN course AS c ON sc.Cid = c.Cid
JOIN teacher AS t ON c.Tid = t.Tid;
3. 查询所有的学生姓名和老师姓名(使用union)
分析:UNION 是一组集合操作,用于将两个SELECT语句的结果组合到一个结果集中,该结果集包 括属于 union 中 SELECT 语句的所有行。
SELECT
s.Sname
FROM
student AS s UNION
SELECT
t.Tname
FROM
teacher AS t;
4.修改Course表Cname字段类型为nvarchar,长度为100
分析:ALTER TABLE修改列的数据类型。直接使用语法套进去即可。
ALTER TABLE Course ALTER COLUMN Cname NVARCHAR(100);
5. 查询各学生的姓名、年龄(只按年份来计算)
分析:GETDATE() 当前的系统日期。
SELECT
s.Sname,
YEAR ( getdate() ) - YEAR ( s.Sage ) AS 年龄
FROM
student AS s;
6. 查询 1990 年出生的学生信息
分析:使用YEAR(date) 返回指定日期的年份数值
SELECT * FROM student AS s
WHERE YEAR ( s.Sage ) = '1990';
7、查询名字中含有「风」字的学生信息
分析: LIKE查找包指定含字符串的行。
通配符百分比( % ):任何零个或多个字符的字符串。
下划线( _ )通配符:任何单个字符。
SELECT * FROM Student R
WHERE R.Sname LIKE '_风%'
8.查询出只选修两门课程的学生学号和姓名
分析:这里需要查询两门课程,所以我使用子查询直接等于2
SELECT
s.sid AS 学号,
s.Sname AS 姓名
FROM
student AS s
WHERE
2 = ( SELECT COUNT(*) FROM sc WHERE sc.Sid = s.Sid );
9.查询成绩表中各科成绩前三名的信息以及排名
分析:COUNT() 函数返回每个组中的行数。DISTINCT 子句检索指定列列表中的唯一不同值,换句话说,它从结果集中删除列中的重复值。 DISTINCT 子句将所有 NULL 值视为相同的值。
SELECT s.*,
sc.Cid,
sc.score,
( SELECT COUNT(DISTINCT t.score)
FROM sc AS t
WHERE t.Cid = sc.Cid AND t.score >= sc.score ) AS 排名
FROM sc
JOIN student AS s
ON sc.Sid = s.Sid
WHERE ( SELECT COUNT(*)
FROM sc AS t
WHERE t.Cid = sc.Cid
AND t.score >= sc.score ) <= 3
ORDER BY
sc.Cid,
sc.score DESC;
10.检索" 01 "课程分数小于 60,按分数降序排列的学生信息和
分析:用and满足where的要求小于60,查询成绩DESC倒序
SELECT
s.*,
sc.score
FROM
student AS s
JOIN sc ON s.Sid = sc.Sid
WHERE
sc.Cid = '01'
AND sc.score < 60
ORDER BY
sc.score DESC;
11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
分析:HAVING 子句通常与[GROUP BY]子句一起使用,以根据指定的条件列表过滤分组。
使用SUM()以获得总成绩
SELECT S.Sid,N.Sname,A.Cid ,
SUM(S.score) AS 平均成绩
FROM
SC S
LEFT JOIN
Student N
ON N.Sid=S.Sid
LEFT JOIN
Course A
ON A.Cid=S.Cid
GROUP BY
S.Sid,N.Sname,A.Cid
HAVING
SUM(S.score)<6
AND A.Cid>2
12.查询没学过"张三"老师讲授的任一门课程的学生姓名
分析: IN 查找值列表中具有值的行,我取消 IN 运算符,所以使用 NOT IN 运算符。DISTINCT 就是要从结果集中删除列中的重复值。
SELECT e.Sname
FROM Student e
WHERE e.Sid
NOT IN (
SELECT DISTINCT Sid
FROM SC e
JOIN Course f
ON f.Cid=e.Cid
JOIN Teacher m
ON m.Tid=f.Tid
WHERE m.Tname='张三'
)
13.查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
分析:这里使用in来查找值列表中具有值的行。并且等于01号同学学习的课程的总数,所以,我这里也用了COUNT()来查找总数。
SELECT *
FROM student AS s
WHERE s.Sid != '01'
AND (SELECT COUNT(*)
FROM sc
WHERE sc.Sid = s.Sid
AND sc.Cid IN
( SELECT sc.Cid FROM sc WHERE sc.Sid = '01' ))
= ( SELECT COUNT(*) FROM sc WHERE sc.Sid = '01' );
14.查询没有学全所有课程的学生的信息
分析:用COUNT()查出课程数,LEFT JOIN ON连接表,GROUP BY 查询哪些数据。首先,COUNT()查询成绩表的总数,然后,HAVINGG 子句过滤小于子查询里面的数据。
SELECT s.Sid,Sname,Sage,Ssex,
COUNT(SC.Cid)AS 课程数
FROM Student s
LEFT JOIN SC
ON s.Sid=SC.Sid
GROUP BY s.Sid,Sname,Sage,Ssex
HAVING
COUNT(SC.Cid)
<(SELECT COUNT(DISTINCT Cid)FROM Course)
15.查询学过「张三」老师授课的同学的信息
分析:从学生表、老师表查询名称为‘张三’。
SELECT *
FROM Student,Teacher S
WHERE
S.Tname='张三'
16.查有成绩的学生信息
分析:从学生表查询所有的学生,使用IN在里面嵌套一个子查询,因为题目要求有成绩的学生,所以大于1,为0就等于没有成绩,所以是大于1。
SELECT s.*
FROM Student s
WHERE Sid IN(
SELECT DISTINCT Sid
FROM SC
WHERE SC.score>1)
17.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
分析:SUM(表达式) 返回表达式中所有的总和,忽略NULL值。
COUNT()返回总的选课数。
SELECT
r.Sid AS 学生编号,r.Sname AS 学生姓名,
(SELECT COUNT(*) FROM SC WHERE SC.Sid=r.Sid)AS 选课总数,
(SELECT SUM(SC.score) FROM SC WHERE SC.Sid=r.Sid) AS 总成绩
FROM
Student r
18.查询在 SC 表存在成绩的学生信息
分析:使用LEFT JOIN ON 表与表之间的连接,ORDER BY 查询。
SELECT q.sid,q.score,w.sname,w.Sage,w.Ssex
FROM SC q
LEFT JOIN Student w
ON w.Sid=q.Sid
ORDER BY q.score