数据库操作

-- 3.17 查询学生姓名、学号、所在系
SELECT
Sname '姓名',
Sno '学号',
Sdept '所在系'
FROM
student

-- 3.19 查询学生姓名、出生年月
SELECT
Sname '姓名',
2021-Sage '出生年月'
FROM
student;

-- 3.20 查询学生姓名、所在系(Lower Case)
SELECT
Sname '姓名',
LOWER( Sdept ) '所在系'
FROM
student;

-- 3.21 查询选修了课程的学生学号(No repeat)
SELECT DISTINCT
Sno
FROM
SC;

-- 3.25 查询年龄在20-23的学生姓名、系别和年龄
SELECT
Sname,
Sdept,
Sage
FROM
student
WHERE
Sage BETWEEN 20
AND 23;

-- 3.26 查询年龄不在20-23的学生姓名、系别和年龄
SELECT
Sname,
Sdept,
Sage
FROM
student
WHERE
Sage not BETWEEN 20
AND 23;

-- 3.27 查询CS、MA和IS的学生情况
SELECT
*
FROM
student
WHERE
Sdept IN ( 'CS', 'MA', 'IS' );

-- 在做查询的时候,如果使用通配符要用LIKE,如果没有通配符则 LIKE和‘=’没有区别
-- 3.32 查询名字中第二个字为‘立'的同学信息
-- ASCII 编码情况下 两个 '_' 代表一个汉字。
SELECT
*
FROM
student
WHERE
Sname LIKE '_立%';

-- 3.33 查询不姓'袁'的同学。
SELECT
*
FROM
student
WHERE
Sname NOT LIKE '袁%';

-- 3.34 查询DB_Design课程的课程号和学分。
-- '' 表示转义字符后面的 ‘_’ 不会被翻译为 通配符。 现在不需要加 ESCAPE '' 了。
SELECT
Cno,
Ccredit
FROM
Course
WHERE
Cname LIKE 'DB_Design';

-- 3.35 查询以 'DB_' 开头 倒数第三个字符为 'i' 的课程。
SELECT
*
FROM
course
WHERE
Cname LIKE 'DB_%i__';

-- 3.41 查询学生总人数
SELECT
count(*)
FROM
student;

-- 3.42 查询选修了课程的学生人数。
SELECT
COUNT( DISTINCT Sno )
FROM
Sc;

-- 3.45 查询学生201215121选修课程总学分数
SELECT
SUM( Ccredit )
FROM
sc
LEFT JOIN course ON sc.Cno = course.Cno
WHERE
Sno = '201215121';

-- 聚集函数只能用于SELECT子句,和GROUP BY 中的HAVING 子句。
-- 3.47 查询选修了二门以上课程的学生的学号。
SELECT
Sno
FROM
sc
GROUP BY
Sno
HAVING
count(*)>2;

-- 3.48 查询平均成绩大于85的学生学号
SELECT
Sno
FROM
sc
GROUP BY
Sno
HAVING
AVG( Grade )> 85;

-- 3.51 查询选修2号课程并且成绩在88以上的学生姓名、学号。
SELECT
student.Sname,
student.Sno
FROM
sc
LEFT JOIN student ON sc.Sno = student.Sno
WHERE
sc.Cno = '2'
AND sc.Grade > 88;

-- 3.52 查询每一门课程的先修课的先修课。
SELECT
A.Cno,
B.Cpno
FROM
course AS A
LEFT JOIN course AS B ON A.Cpno = B.Cno
WHERE
B.Cpno IS NOT NULL;

-- 3.54 查询学生名、选修课名、成绩
SELECT
student.Sname,
course.Cname,
sc.Grade
FROM
student
LEFT JOIN sc ON sc.Sno = student.Sno
LEFT JOIN course ON course.Cno = sc.Cno
WHERE
sc.Grade IS NOT NULL;

-- 3.55 查询和刘晨在同一个系学习的学生。
SELECT
student.Sname
FROM
student
WHERE
student.Sdept IN ( SELECT student.Sdept FROM student WHERE student.Sname = '刘晨' );

-- 3.56 查询 选修了 ‘信息系统’ 的学生的学号和姓名。
-- 同样可以选用两个链接去完成。或者嵌套查询。

-- 3.57 找出每个学生超过他自己的选修课程平均成绩的课程号。 子查询。
-- 解释一下 就是 外层X 传值进入内层, 内层计算之后 值替代内层位置 外层计算, 然后循环下去。
-- 求相关子查询不能像求解 不相关子查询那样依次将子查询求解出来, 然后求解夫查询。 内层循环由于与外层查询有关,因此必须反复求值。
SELECT
Sno,
Cno,
Grade
FROM
sc x
WHERE
Grade >=(
SELECT
avg( Grade )
FROM
sc y
WHERE
y.Sno = x.Sno
);

-- 3.58 查询非计算机科学系中比计算机科学系任意一个学生年龄小的学生姓名、年龄。
SELECT
Sname,
Sage
FROM
student
WHERE
Sage < ANY ( SELECT Sage FROM student WHERE Sdept = 'CS' )
AND student.Sdept <> 'CS'

SELECT
Sname,
Sage
FROM
student
WHERE
Sage < ( SELECT MAX(Sage) FROM student WHERE Sdept = 'CS' )
AND student.Sdept <> 'CS'

-- 3.60 查询所有选修了一号课程的学生的姓名
-- EXISTS 只返回真假。 下面的程序中,外层的Student 想内层传输一个元组, 内层用改元组做完查询之后,如果没有信息则范围False, 如果有信息返回true, 循环执行下去就得了。
SELECT
Sname
FROM
student
WHERE
EXISTS (
SELECT
*
FROM
sc
WHERE
sno = student.sno
AND Cno = '1')

-- 3.62 有没有将所有科目都修一边的学生?把名字列出来。 理解了, 但是这家伙 有点。。。。

SELECT
Sname
FROM
student
WHERE
NOT EXISTS (
SELECT
*
FROM
course
WHERE
NOT EXISTS ( SELECT * FROM sc WHERE sno = student.Sno AND cno = course.Cno ))

-- 3.65 查询选修了1和2 的学生
SELECT
*
FROM
sc
WHERE
sc.Cno = '1' UNION
SELECT
*
FROM
sc
WHERE
sc.Cno = '2';

-- 3.66 查询计算机科学系的学生和年龄不大于19的学生的交集(INTERSECT好像是废弃了。)。
SELECT * from student WHERE Sdept='CS' and student.Sage<=19;

-- 3.68 查询计算机科学系的学生与年龄不大于19岁的学生的差集。
-- 翻译成人话就是: 是计算机科学系的学生并且年龄大于19岁。
-- 同样被废弃了。

-- 临时派生表 不仅可以出现在 where中(一般搭配 in , ALL , ANY) 也可以出现在From 子句中。

-- 3.72 查询每个系,求学生的平均年龄,并将结果存入数据库。
CREATE TABLE Dept_age (
Sdept CHAR ( 15 ),
Avg_age SMALLINT)

INSERT INTO dept_age ( Sdept, Avg_age ) SELECT
Sdept,
Avg( Sage )
FROM
student
GROUP BY
Sdept;

posted @ 2021-03-16 02:28  X-POWER  阅读(244)  评论(0编辑  收藏  举报