SQL SERVER-练习题目1

SQL SERVER-练习题目1

一、题目素材

1.基础表结构

-- 学生表
CREATE TABLE Student(
    SId VARCHAR(10) PRIMARY KEY,
    Sname VARCHAR(10) NOT NULL,
    Sage DATE NOT NULL,
    Seex CHAR(2) NOT NULL
);
INSERT INTO Student VALUES('01','张三','2000-01-01','男'),('02','李四','2001-05-12','女'),('03','王五','1999-08-20','男');

-- 课程表
CREATE TABLE Course(
    CId VARCHAR(10) PRIMARY KEY,
    Cname VARCHAR(20) NOT NULL,
    TId VARCHAR(10) NOT NULL
);

INSERT INTO Course VALUES('3-105','数学','T01'),('3-245','语文','T02'),('6-166','英语','T03');

-- 成绩表
CREATE TABLE SC(
    SId VARCHAR(10) REFERENCES Student(SId),
    CId VARCHAR(10) REFERENCES Course(CId),
    Score DECIMAL(5,1) NOT NULL,
    PRIMARY KEY(SId,CId)
);
INSERT INTO SC VALUES ('01', '3-105', 85.5),('01', '3-245', 72.0),('02', '3-105', 90.0),('03', '6-166', 88.5);

-- 教师表(Teacher)
CREATE TABLE Teacher (
    TId VARCHAR(10) PRIMARY KEY,
    Tname VARCHAR(10) NOT NULL,
    Depart VARCHAR(20) NOT NULL
);
INSERT INTO Teacher VALUES ('T01', '赵老师', '数学系'),('T02', '钱老师', '中文系');

二、经典习题与要求

1.基础查询

题目1:查询所有学生的学号、姓名及其年龄(精确到年)。 – 题目2:查询成绩表中分数在 80 到 90 分之间的记录,按分数降序排列。

2.多表关联查询

题目3:查询选修了“数学”课程的学生姓名及成绩。 – 题目4:查询每位教师的姓名及其所授课程的名称。

3. ‌聚合与分组

题目5‌:统计每门课程的平均分,并显示课程名和平均分(保留一位小数)。 – 题目6‌:查询选修超过 2 门课程的学生学号及选课数量。

4.高级查询

题目7:查询每科成绩的前两名学生(使用窗口函数 ROW_NUMBER())。 – 题目8:查询“数学”课程成绩高于该课程平均分的学生信息。

5.数据操作

题目9:将学号为 03 的学生年龄修改为 25 岁。 – 题目10:删除成绩表中分数低于 60 分的记录

三、参考题目

1.基础查询答案

-- 题目1、查询所有学生的学号、姓名及其年龄(精确到年)。
select SId as '学号',Sname as '姓名',DATEDIFF(YEAR,Sage,GETDATE()) AS '年龄' FROM Stuedent;

优化写法:
SELECT 
    SId AS 学号,
    Sname AS 姓名,
    DATEDIFF(YEAR, Sage, GETDATE()) - 
        CASE WHEN DATEADD(YEAR, DATEDIFF(YEAR, Sage, GETDATE()), Sage) > GETDATE() 
             THEN 1 
             ELSE 0 
        END AS 年龄
FROM Student;
-- 题目2、查询成绩表中分数在 80 到 90 分之间的记录,按分数降序排列。
select * from SC where Score between 80 and 90 order by Score desc;

优化写法:没有
-- 题目3、查询选修了“数学”课程的学生姓名及成绩。
select Student.Sname as '学生姓名',Sc.Score as '成绩' from Student left outer join Sc on Student.SId = Sc.SId where Cid = (select CId from Course where Cname = '数学');

优化写法:
select S.Sname,SC.score from SC JOIN course C on C.Cid = SC.Cid and C.Cname = '数学' Join Student S on S.SId = SC.SId;
-- 题目4、查询每位教师的姓名及其所授课程的名称。
select Teacher.Tname as '教师姓名',Course.Cname as '课程' from teacher left outer join Course on Teacher.Tid = Course.Tid;

优化写法:
select T.Tname as '教师姓名',COALESCE(C.Cname,'无授课') as '课程' from teacher T left outer join Course C on T.Tid = C.Tid;
-- 题目5、统计每门课程的平均分,并显示课程名和平均分(保留一位小数)。
Select Course.Cname as '课程',CONVERT(DECIMAL(5,1),AVG(SC.Score)) as '平均分' from Course left outer join SC on Course.Cid = SC.CId GROUP BY Course.Cname;

优化写法:没有
select SId as '学生学号',count(CId) as '课程数量' FROM SC GROUP BY Sid having count(CId) > 2;
-- 题目6、查询选修超过 2 门课程的学生学号及选课数量。
Select Student.SId as '学生学号',count(SC.CId) as '课程数量' from Student left outer join SC on Student.SId = SC.SId GROUP BY Student.SId having count(SC.CId) > 2 ; 

优化写法:select SId as '学生学号',count(CId) as '课程数量' FROM SC GROUP BY Sid having count(CId) >= 2;
-- 题目7、查询每科成绩的前两名学生(使用窗口函数 `ROW_NUMBER()`)。
select L.Sname,Course.Cname,L.Score FROM Course left outer join (select Student.Sname,B.Cid,B.Score FROM Student left outer JOIN (select CId,Sid,Score FROM (select *,ROW_NUMBER() OVER (PARTITION BY Cid ORDER BY Score Desc) as RANK FROM SC) as T where RANK <= 2) as B on Student.Sid = B.Sid) AS L on Course.Cid = L.Cid;

WITH RankedScores AS (
    SELECT 
        S.Sname,
        C.Cname,
        SC.Score,
        ROW_NUMBER() OVER (PARTITION BY SC.CId ORDER BY SC.Score DESC) AS RN
    FROM SC
    JOIN Student S ON SC.SId = S.SId
    JOIN Course C ON SC.CId = C.CId
)
SELECT Sname, Cname, Score
FROM RankedScores
WHERE RN <= 2;
-- 题目8、查询“数学”课程成绩高于该课程平均分的学生信息。
select A.SId,A.CId,A.Score FROM (select SC.SId,Course.CId,SC.Score FROM SC LEFT OUTER JOIN course on SC.Cid = course.CId) AS A Left outer Join (select Course.Cname,Course.Cid,T.Score FROM Course left outer join (select SC.CId,AVG(SC.Score) as Score FROM SC GROUP BY SC.CId) as T on Course.CId = T.CId where Course.Cname= '数学') AS B ON A.CId = B.CId where A.Score > B.Score;

优化写法:
select S.SId,S.Sname,SC.Score,SC.CId FROM Student S Join SC ON S.SId = SC.SId Join Course C ON SC.CId = C.CId where C.Cname='数学' AND SC.Score > (SELECT AVG(SC.Score) FROM SC JOIN course ON SC.CId = course.CId WHERE COURSE.CNAME='数学');
--题目9、将学号为 `03` 的学生年龄修改为 `25` 岁。
UPDATE STUDENT SET SAGE = DATEADD(YEAR,-25,GETDATE()) WHERE SID = '03';
--题目10、删除成绩表中分数低于 60 分的记录
delete from SC where score < 60;

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注