好——下面给你每题对应的 T-SQL(SQL Server)答案。我假设你是在 SQL Server 上运行(语句用到 GETDATE()
、CAST
、窗口函数/子查询等),并且统一使用下面的 年龄计算表达式(精确到生日):
-- 年龄表达式(可直接复制到下面的查询里)
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END
关于 ssex 的说明:你的数据里 ssex
的编码在示例里好像不一致(0/1 与性别的对应不明确)。下面的查询里我会在涉及“女生/男生”的题目处写成 ssex = 0
(你若实际 0=男、1=女,请把条件反过来即可)。
下面按题号给出 SQL 语句(每条独立可执行):
- 查询全体学生的学号、姓名与年龄
SELECT sno, sname,
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END AS age
FROM StuInfo.dbo.S;
- 查询计算机系(sdept='计算机')的学生学号、姓名
SELECT sno, sname
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) = N'计算机';
- 查询计算机系所有的女生姓名和年龄(假设
ssex = 0
表示女;若你系统相反请改为ssex = 1
)
SELECT sname,
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END AS age
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) = N'计算机'
AND ssex = 0;
- 查询选修了课程的学生学号(去重)
SELECT DISTINCT sno
FROM StuInfo.dbo.SC;
- 查询所有年龄在30岁以下的学生姓名及其年龄
SELECT sname,
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END AS age
FROM StuInfo.dbo.S
WHERE (DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END) < 30;
- 查询考试有不及格(还包括未参加考试,即
grade < 60 OR grade IS NULL
)的学生的学号
SELECT DISTINCT sno
FROM StuInfo.dbo.SC
WHERE grade < 60 OR grade IS NULL;
- 查询年龄在25-30岁之间(包含25和30岁)的学生的姓名和年龄
SELECT sname,
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END AS age
FROM StuInfo.dbo.S
WHERE (DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END) BETWEEN 25 AND 30;
- 查询计算机,数学系和信息系学生的姓名
SELECT sname, sdept
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) IN (N'计算机', N'数学', N'信息工程', N'信息'); -- 兼顾可能的写法
- 查询不是计算机和信息工程系的学生姓名
SELECT sname, sdept
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) NOT IN (N'计算机', N'信息工程');
- 查询所有姓刘的学生姓名、学号
SELECT sno, sname
FROM StuInfo.dbo.S
WHERE sname LIKE N'刘%';
- 查询与数据库相关课程的课程号和名称(模糊匹配“数据库”)
SELECT cno, cname
FROM StuInfo.dbo.C
WHERE cname LIKE N'%数据库%';
- 查询未录入成绩的学生的学号和相应的课程号(grade IS NULL)
SELECT sno, cno
FROM StuInfo.dbo.SC
WHERE grade IS NULL;
- 查询计算机系年龄在30岁以下的学生姓名
SELECT sname
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) = N'计算机'
AND (DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END) < 30;
- 查询选修了0102号课程的学生学号及其成绩,按学号升序
SELECT sno, grade
FROM StuInfo.dbo.SC
WHERE cno = '0102'
ORDER BY sno ASC;
- 查询选修了0101号课程的学生学号及其成绩,按分数降序排列
SELECT sno, grade
FROM StuInfo.dbo.SC
WHERE cno = '0101'
ORDER BY grade DESC;
- 查询学生总人数
SELECT COUNT(*) AS total_students
FROM StuInfo.dbo.S;
- 查询选修了课程的学生人数(去重学号计数)
SELECT COUNT(DISTINCT sno) AS students_who_taken_course
FROM StuInfo.dbo.SC;
- 计算0101号课程的平均成绩(排除 NULL)
SELECT AVG(CAST(grade AS FLOAT)) AS avg_grade_0101
FROM StuInfo.dbo.SC
WHERE cno = '0101' AND grade IS NOT NULL;
- 计算计算机系学生的平均年龄
SELECT AVG(
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END
) AS avg_age
FROM StuInfo.dbo.S
WHERE LTRIM(RTRIM(sdept)) = N'计算机';
- 查询选修了0102号课程的学生最低分数
SELECT MIN(grade) AS min_grade_0102
FROM StuInfo.dbo.SC
WHERE cno = '0102' AND grade IS NOT NULL;
- 查询学生 001108 选修课程的总学分数(若要只统计已录成绩的课可加
AND sc.grade IS NOT NULL
)
SELECT s.sno,
SUM(COALESCE(c.ccredit,0)) AS total_credits
FROM StuInfo.dbo.SC sc
JOIN StuInfo.dbo.C c ON sc.cno = c.cno
JOIN StuInfo.dbo.S s ON sc.sno = s.sno
WHERE sc.sno = '001108'
GROUP BY s.sno;
- 查询每门课程号及其对应的选课人数
SELECT sc.cno, COUNT(sc.sno) AS student_count
FROM StuInfo.dbo.SC sc
GROUP BY sc.cno;
- 计算每门课程及其平均分(排除 NULL)
SELECT c.cno, c.cname, AVG(CAST(sc.grade AS FLOAT)) AS avg_grade
FROM StuInfo.dbo.C c
LEFT JOIN StuInfo.dbo.SC sc ON c.cno = sc.cno AND sc.grade IS NOT NULL
GROUP BY c.cno, c.cname;
- 计算选修了3门课程以上的学生学号(题目要求“超过3门”)
SELECT sno
FROM StuInfo.dbo.SC
GROUP BY sno
HAVING COUNT(*) > 3;
- 查询每个学生的学号及课程的平均分
SELECT sc.sno, AVG(CAST(sc.grade AS FLOAT)) AS avg_grade
FROM StuInfo.dbo.SC sc
WHERE sc.grade IS NOT NULL
GROUP BY sc.sno;
- 查询所有课程的平均学分
SELECT AVG(CAST(ccredit AS FLOAT)) AS avg_credit
FROM StuInfo.dbo.C;
- 查询与“林一帆”在同一个系学习的学生学号和姓名(不包括林一帆本人)
SELECT s2.sno, s2.sname
FROM StuInfo.dbo.S s1
JOIN StuInfo.dbo.S s2 ON LTRIM(RTRIM(s1.sdept)) = LTRIM(RTRIM(s2.sdept))
WHERE s1.sname = N'林一帆' AND s2.sno <> s1.sno;
- 查询平均分在75分以下的学生信息(学号、姓名、平均分)
SELECT t.sno, s.sname, t.avg_grade
FROM (
SELECT sno, AVG(CAST(grade AS FLOAT)) AS avg_grade
FROM StuInfo.dbo.SC
WHERE grade IS NOT NULL
GROUP BY sno
) t
JOIN StuInfo.dbo.S s ON s.sno = t.sno
WHERE t.avg_grade < 75;
- 查询选修0101号课程且成绩在80分以上的所有学生姓名、学号
SELECT s.sno, s.sname, sc.grade
FROM StuInfo.dbo.SC sc
JOIN StuInfo.dbo.S s ON sc.sno = s.sno
WHERE sc.cno = '0101' AND sc.grade >= 80;
- 查询每个学生的学号、姓名、选修的课程名及其成绩
SELECT s.sno, s.sname, c.cname, sc.grade
FROM StuInfo.dbo.S s
LEFT JOIN StuInfo.dbo.SC sc ON s.sno = sc.sno
LEFT JOIN StuInfo.dbo.C c ON sc.cno = c.cno
ORDER BY s.sno;
- 显示每个系的学生的平均年龄
SELECT LTRIM(RTRIM(sdept)) AS department,
AVG(
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END
) AS avg_age
FROM StuInfo.dbo.S
GROUP BY LTRIM(RTRIM(sdept));
- 查询“计算机”系所有选修了“数据库原理”课程的学生姓名
(假设课程名包含“数据库原理”,或你也可直接用 cno = '0106')
SELECT DISTINCT s.sno, s.sname
FROM StuInfo.dbo.S s
JOIN StuInfo.dbo.SC sc ON s.sno = sc.sno
JOIN StuInfo.dbo.C c ON sc.cno = c.cno
WHERE LTRIM(RTRIM(s.sdept)) = N'计算机'
AND c.cname LIKE N'%数据库原理%';
- 显示至少有5名学生选修的课程的平均分数及其课程名称
SELECT c.cno, c.cname, AVG(CAST(sc.grade AS FLOAT)) AS avg_grade, COUNT(sc.sno) AS student_count
FROM StuInfo.dbo.C c
JOIN StuInfo.dbo.SC sc ON c.cno = sc.cno AND sc.grade IS NOT NULL
GROUP BY c.cno, c.cname
HAVING COUNT(sc.sno) >= 5;
- 查询每个人选修的课程数,显示其学号及课程数
SELECT s.sno, s.sname, COUNT(sc.cno) AS course_count
FROM StuInfo.dbo.S s
LEFT JOIN StuInfo.dbo.SC sc ON s.sno = sc.sno
GROUP BY s.sno, s.sname;
- 查询有3门(包含3门)以上课程是70分以上(包含70分)的学生的学号及课程数
SELECT sno, COUNT(*) AS count_ge_70
FROM StuInfo.dbo.SC
WHERE grade >= 70
GROUP BY sno
HAVING COUNT(*) >= 3;
- 查询“C++程序设计”这门课程的学生成绩(先找课程号,再查)
-- 方法一:按课程名模糊匹配
SELECT sc.sno, s.sname, sc.grade
FROM StuInfo.dbo.SC sc
JOIN StuInfo.dbo.C c ON sc.cno = c.cno
JOIN StuInfo.dbo.S s ON sc.sno = s.sno
WHERE c.cname LIKE N'%C++程序设计%';
- 求年龄大于学生平均年龄的男学生姓名和年龄(假设
ssex = 1
表示男;若反过来改条件)
;WITH Ages AS (
SELECT sno, sname,
DATEDIFF(year, sbirth, GETDATE())
- CASE WHEN DATEADD(year, DATEDIFF(year, sbirth, GETDATE()), sbirth) > GETDATE() THEN 1 ELSE 0 END AS age
FROM StuInfo.dbo.S
)
SELECT a.sno, a.sname, a.age
FROM Ages a
CROSS JOIN (SELECT AVG(age) AS avg_age FROM Ages) av
WHERE a.age > av.avg_age
AND EXISTS (SELECT 1 FROM StuInfo.dbo.S s WHERE s.sno = a.sno AND s.ssex = 1);
- 查询成绩高于该门课程平均分的学生学号和课程号
SELECT sc.sno, sc.cno, sc.grade
FROM StuInfo.dbo.SC sc
WHERE sc.grade IS NOT NULL
AND sc.grade >
(SELECT AVG(CAST(grade AS FLOAT)) FROM StuInfo.dbo.SC WHERE cno = sc.cno AND grade IS NOT NULL);
- 查询每门课程最高分的学生学号和课程号
SELECT sc.cno, sc.sno, sc.grade
FROM StuInfo.dbo.SC sc
JOIN (
SELECT cno, MAX(grade) AS max_grade
FROM StuInfo.dbo.SC
GROUP BY cno
) m ON sc.cno = m.cno AND sc.grade = m.max_grade;
- 查询每门课程最低分的学生学号
SELECT sc.cno, sc.sno, sc.grade
FROM StuInfo.dbo.SC sc
JOIN (
SELECT cno, MIN(grade) AS min_grade
FROM StuInfo.dbo.SC
WHERE grade IS NOT NULL
GROUP BY cno
) m ON sc.cno = m.cno AND sc.grade = m.min_grade;
- 查询每门课程的最低分及其课程名称
SELECT c.cno, c.cname, m.min_grade
FROM StuInfo.dbo.C c
JOIN (
SELECT cno, MIN(grade) AS min_grade
FROM StuInfo.dbo.SC
WHERE grade IS NOT NULL
GROUP BY cno
) m ON c.cno = m.cno;
- 查询所有学生及其选修课程的课程名称、成绩(若未选课仍显示学生)
SELECT s.sno, s.sname, c.cname, sc.grade
FROM StuInfo.dbo.S s
LEFT JOIN StuInfo.dbo.SC sc ON s.sno = sc.sno
LEFT JOIN StuInfo.dbo.C c ON sc.cno = c.cno
ORDER BY s.sno;
- 显示所有课程的成绩,按照课程号升序排列,成绩降序排列(观察 NULL 排序位置)
SELECT sc.cno, sc.sno, sc.grade
FROM StuInfo.dbo.SC sc
ORDER BY sc.cno ASC, sc.grade DESC;
备注:在 SQL Server 中
NULL
在ORDER BY ... DESC
时通常会被排在最后还是最前取决于版本/实现,可通过ORDER BY sc.cno, CASE WHEN sc.grade IS NULL THEN 1 ELSE 0 END ASC, sc.grade DESC
明确控制NULL
显示在前或后。
如果你要我:
- 把这些 SQL 放到一个
.sql
文件里(按题号注释分组),我可以直接把整理好的文本给你; - 或者把某几题改成更“严格”的实现(例如:只统计已登记学分、只统计已录成绩、或按
sdept
的不同写法兼容)——告诉我你想要的格式,我直接改好给你。
另外提醒两点:
- 上面含有若干处对
sdept
、sname
、cname
的字符串匹配,我用了LTRIM(RTRIM(...))
或LIKE
来提高鲁棒性; - 关于
ssex
的编码(男/女 对应 0/1)如前所述不一致的话请按你数据实际值把ssex = 0
/= 1
对调——我可以帮你统一检查并修正条件。
要我直接把这些查询打包成一个带注释的 .sql
文件吗?还是先把哪几题的输出示例跑一遍(给出预期结果示例)?
文章作者:zhexian
文章标题:数据库上机答案
文章链接:https://zhexiange.com/34.html
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自zhexian !
文章标题:数据库上机答案
文章链接:https://zhexiange.com/34.html
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明来自zhexian !
手机扫码阅读