数据库练习(一)

文章里面的数据和题目来自博文: https://blog.csdn.net/mrbcy/article/details/68965271

文章目录

    • 首先我们来康康表:
      • teachers:
      • students:
      • cources:
      • scores:
    • 题目:
    • 我们来开始做题:
      • 1. 查询Student表中的所有记录的Sname、Ssex和Class列。
      • 2.查询教师所有的单位即不重复的Depart列
      • 3.查询Student表的所有记录。
      • 4.查询Score表中成绩在60到80之间的所有记录。
      • 5.查询Score表中成绩为85,86或88的记录。
      • 6.查询Student表中“95031”班或性别为“女”的同学记录。
      • 7.以Class降序查询Student表的所有记录。
      • 8.以Cno升序、Degree降序查询Score表的所有记录。
        • 复合排序
      • 9.查询“95031”班的学生人数。
        • [SQL COUNT](https://www.w3school.com.cn/sql/sql_func_count.asp)
      • 10.查询Score表中的最高分的学生学号和课程号。
        • LIMIT 语句解析
      • 11.查询‘3-105’号课程的平均分。
      • *12.查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
        • [SQL GROUP BY 语句](https://www.w3school.com.cn/sql/sql_groupby.asp)
        • [SQL HAVING 语句](https://www.w3school.com.cn/sql/sql_having.asp)
      • *13.查询最低分大于70,最高分小于90的Sno列。
      • *14.查询所有学生的Sname、Cno和Degree列。
        • *内连接
      • 15.查询所有学生的Sno、Cname和Degree列。
      • *16.查询所有学生的Sname、Cname和Degree列。
      • ? 此问题存在疑惑,可跳过17.查询“95033”班所选课程的平均分。
      • 18.假设使用如下命令建立了一个grade表:

首先我们来康康表:

teachers:

+------+-------+------+---------------------+--------+------------+
| tno  | tname | tsex | tbirthday           | prof   | depart     |
+------+-------+------+---------------------+--------+------------+
| 804  | 李诚  || 1958-12-02 00:00:00 | 副教授 | 计算机系   |
| 856  | 张旭  || 1969-03-12 00:00:00 | 讲师   | 电子工程系 |
| 825  | 王萍  || 1972-05-05 00:00:00 | 助教   | 计算机系   |
| 831  | 刘冰  || 1977-08-14 00:00:00 | 助教   | 电子工程系 |
+------+-------+------+---------------------+--------+------------+

students:

+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 108 | 曾华  || 1977-09-01 00:00:00 | 95033 |
| 105 | 匡明  || 1975-10-02 00:00:00 | 95031 |
| 107 | 王丽  || 1976-01-23 00:00:00 | 95033 |
| 101 | 李军  || 1976-02-20 00:00:00 | 95033 |
| 109 | 王芳  || 1975-02-10 00:00:00 | 95031 |
| 103 | 陆君  || 1974-06-03 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+

cources:

+-------+------------+-----+
| cno   | cname      | tno |
+-------+------------+-----+
| 3-105 | 计算机导论 | 825 |
| 3-245 | 操作系统   | 804 |
| 6-166 | 数据电路   | 856 |
| 9-888 | 高等数学   | 100 |
+-------+------------+-----+

scores:

+-----+-------+--------+
| sno | cno   | degree |
+-----+-------+--------+
| 103 | 3-245 |   86.0 |
| 105 | 3-245 |   75.0 |
| 109 | 3-245 |   68.0 |
| 103 | 3-105 |   92.0 |
| 105 | 3-105 |   88.0 |
| 109 | 3-105 |   76.0 |
| 101 | 3-105 |   64.0 |
| 107 | 3-105 |   91.0 |
| 108 | 3-105 |   78.0 |
| 101 | 6-166 |   85.0 |
| 107 | 6-106 |   79.0 |
| 108 | 6-166 |   81.0 |
+-----+-------+--------+

题目:

1、 查询Student表中的所有记录的Sname、Ssex和Class列。
2、 查询教师所有的单位即不重复的Depart列。
3、 查询Student表的所有记录。
4、 查询Score表中成绩在60到80之间的所有记录。
5、 查询Score表中成绩为85,86或88的记录。
6、 查询Student表中“95031”班或性别为“女”的同学记录。
7、 以Class降序查询Student表的所有记录。
8、 以Cno升序、Degree降序查询Score表的所有记录。
9、 查询“95031”班的学生人数。
10、查询Score表中的最高分的学生学号和课程号。
11、查询‘3-105’号课程的平均分。
12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。
13、查询最低分大于70,最高分小于90的Sno列。
14、查询所有学生的Sname、Cno和Degree列。
15、查询所有学生的Sno、Cname和Degree列。
16、查询所有学生的Sname、Cname和Degree列。
17、查询“95033”班所选课程的平均分。
18、假设使用如下命令建立了一个grade表:
create table grade(low   number(3,0),upp   number(3),rank   char(1));
insert into grade values(90,100,’A’);
insert into grade values(80,89,’B’);
insert into grade values(70,79,’C’);
insert into grade values(60,69,’D’);
insert into grade values(0,59,’E’);
commit;
现查询所有同学的Sno、Cno和rank列。
19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。
20、查询score中选学一门以上课程的同学中分数为非最高分成绩的记录。
21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。
22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。
23、查询“张旭“教师任课的学生成绩。
24、查询选修某课程的同学人数多于5人的教师姓名。
25、查询95033班和95031班全体学生的记录。
26、查询存在有85分以上成绩的课程Cno.
27、查询出“计算机系“教师所教课程的成绩表。
28、查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。
29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。
30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree.
31、查询所有教师和同学的name、sex和birthday.
32、查询所有“女”教师和“女”同学的name、sex和birthday.
33、查询成绩比该课程平均成绩低的同学的成绩表。
34、查询所有任课教师的Tname和Depart.
35  查询所有未讲课的教师的Tname和Depart. 
36、查询至少有2名男生的班号。
37、查询Student表中不姓“王”的同学记录。
38、查询Student表中每个学生的姓名和年龄。
39、查询Student表中最大和最小的Sbirthday日期值。
40、以班号和年龄从大到小的顺序查询Student表中的全部记录。
41、查询“男”教师及其所上的课程。
42、查询最高分同学的Sno、Cno和Degree列。
43、查询和“李军”同性别的所有同学的Sname.
44、查询和“李军”同性别并同班的同学Sname.
45、查询所有选修“计算机导论”课程的“男”同学的成绩表


我们来开始做题:

1. 查询Student表中的所有记录的Sname、Ssex和Class列。

这个是入门级别的,我们看看需要使用啥语句:

mysql> SELECT Sname, Ssex, Class from students;
结果:
+-------+------+-------+
| Sname | Ssex | Class |
+-------+------+-------+
| 曾华  || 95033 |
| 匡明  || 95031 |
| 王丽  || 95033 |
| 李军  || 95033 |
| 王芳  || 95031 |
| 陆君  || 95031 |
+-------+------+-------+

2.查询教师所有的单位即不重复的Depart列

mysql> SELECT * FROM teachers;
+------+-------+------+---------------------+--------+------------+
| tno  | tname | tsex | tbirthday           | prof   | depart     |
+------+-------+------+---------------------+--------+------------+
| 804  | 李诚  || 1958-12-02 00:00:00 | 副教授 | 计算机系   |
| 856  | 张旭  || 1969-03-12 00:00:00 | 讲师   | 电子工程系 |
| 825  | 王萍  || 1972-05-05 00:00:00 | 助教   | 计算机系   |
| 831  | 刘冰  || 1977-08-14 00:00:00 | 助教   | 电子工程系 |
+------+-------+------+---------------------+--------+------------+
4 rows in set (0.03 sec)

mysql> SELECT DISTINCT depart
    -> FROM teachers;
+------------+
| depart     |
+------------+
| 计算机系   |
| 电子工程系 |
+------------+

3.查询Student表的所有记录。

mysql> SELECT * FROM students;
+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 108 | 曾华  || 1977-09-01 00:00:00 | 95033 |
| 105 | 匡明  || 1975-10-02 00:00:00 | 95031 |
| 107 | 王丽  || 1976-01-23 00:00:00 | 95033 |
| 101 | 李军  || 1976-02-20 00:00:00 | 95033 |
| 109 | 王芳  || 1975-02-10 00:00:00 | 95031 |
| 103 | 陆君  || 1974-06-03 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+
6 rows in set (0.01 sec)

4.查询Score表中成绩在60到80之间的所有记录。

mysql> SELECT *
    -> FROM scores
    -> WHERE degree BETWEEN 60 AND 80;
+-----+-------+--------+
| sno | cno   | degree |
+-----+-------+--------+
| 105 | 3-245 |   75.0 |
| 109 | 3-245 |   68.0 |
| 109 | 3-105 |   76.0 |
| 101 | 3-105 |   64.0 |
| 108 | 3-105 |   78.0 |
| 107 | 6-106 |   79.0 |
+-----+-------+--------+

5.查询Score表中成绩为85,86或88的记录。

mysql> SELECT *
    -> FROM scores
    -> WHERE degree
    -> IN (85,86,88);
+-----+-------+--------+
| sno | cno   | degree |
+-----+-------+--------+
| 103 | 3-245 |   86.0 |
| 105 | 3-105 |   88.0 |
| 101 | 6-166 |   85.0 |
+-----+-------+--------+

IN 操作符

IN 操作符允许我们在 WHERE 子句中规定多个值。

SQL IN 语法
SELECT column_name(s)
FROM table_name
WHERE column_name IN (value1,value2,…)

6.查询Student表中“95031”班或性别为“女”的同学记录。


mysql> SELECT *
    -> FROM students
    -> WHERE
    -> class = '95031' OR ssex = '女';
+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 105 | 匡明  || 1975-10-02 00:00:00 | 95031 |
| 107 | 王丽  || 1976-01-23 00:00:00 | 95033 |
| 109 | 王芳  || 1975-02-10 00:00:00 | 95031 |
| 103 | 陆君  || 1974-06-03 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+

7.以Class降序查询Student表的所有记录。

mysql> SELECT *
    -> FROM students
    -> ORDER BY class DESC;
+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 108 | 曾华  || 1977-09-01 00:00:00 | 95033 |
| 107 | 王丽  || 1976-01-23 00:00:00 | 95033 |
| 101 | 李军  || 1976-02-20 00:00:00 | 95033 |
| 105 | 匡明  || 1975-10-02 00:00:00 | 95031 |
| 109 | 王芳  || 1975-02-10 00:00:00 | 95031 |
| 103 | 陆君  || 1974-06-03 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+
6 rows in set (0.00 sec)

8.以Cno升序、Degree降序查询Score表的所有记录。

mysql> SELECT *
    -> FROM scores
    -> ORDER BY cno ASC, degree DESC;
+-----+-------+--------+
| sno | cno   | degree |
+-----+-------+--------+
| 103 | 3-105 |   92.0 |
| 107 | 3-105 |   91.0 |
| 105 | 3-105 |   88.0 |
| 108 | 3-105 |   78.0 |
| 109 | 3-105 |   76.0 |
| 101 | 3-105 |   64.0 |
| 103 | 3-245 |   86.0 |
| 105 | 3-245 |   75.0 |
| 109 | 3-245 |   68.0 |
| 107 | 6-106 |   79.0 |
| 101 | 6-166 |   85.0 |
| 108 | 6-166 |   81.0 |
+-----+-------+--------+

复合排序

9.查询“95031”班的学生人数。


mysql> SELECT COUNT(1)
    -> FROM students
    -> WHERE class = '95031';
+----------+
| COUNT(1) |
+----------+
|        3 |
+----------+
1 row in set (0.01 sec)

mysql> SELECT COUNT(*)
    -> FROM students
    -> WHERE class = '95031';
+----------+
| COUNT(*) |
+----------+
|        3 |
+----------+

当然为了更好我们可以这样写

mysql> SELECT COUNT(class) AS CLASSCOUNT
    -> FROM students
    -> WHERE class = '95031';
+------------+
| CLASSCOUNT |
+------------+
|          3 |
+------------+

SQL COUNT

10.查询Score表中的最高分的学生学号和课程号。

mysql> SELECT sno,cno
    -> FROM scores
    -> ORDER BY degree DESC
    -> LIMIT 1;
+-----+-------+
| sno | cno   |
+-----+-------+
| 103 | 3-105 |
+-----+-------+
1 row in set (0.00 sec)

现在这个语句里面,我们发现一个陌生的语法,LIMIT,这是啥?

LIMIT 语句解析

假设有这么一张表名叫ids,只有id一列:

id
---
1
2
3
4
5
...
...
197
198
199
200

执行

SELECT * FROM ids LIMIT 10, 1
输出:

id
---
11

执行

SELECT * FROM ids LIMIT 10, 3
输出:

id
---
11
12
13

执行
`SELECT * FROM ids LIMIT 45, 1
输出:

id
---
46

从以上示例可以看出,LIMIT后的第一个参数是输出记录的初始位置,第二个参数偏移量,偏移多少,输出的条目就是多少。

再看与LIMIT搭配的还有一个OFFSET命令:

执行

SELECT * FROM ids LIMIT 10 OFFSET 2

输出:

id
---
3
4
5
6
7
8
9
10
11
12

执行
SELECT * FROM ids LIMIT 5 OFFSET 2

输出:

id
---
3
4
5
6
7

执行
SELECT * FROM ids LIMIT 5 OFFSET 10
输出:

id
---
11
12
13
14
15

可以看出OFFSET与逗号隔开基本是一样的,唯一的差别就是两个参数的位置前后颠倒了一下。

于是可以考虑这个一个问题:假如某省高考成绩出来了,按照成绩排名,并取出地m名到第n名的学生信息,这时候LIMIT不就可以用上了嘛:

SELECT * FROM list ORDER BY score LIMIT m-1, n - m + 1
————————————————
原文链接:https://blog.csdn.net/sinat_36246371/article/details/54582904

所以看了这个以后,语法可以改成

mysql> SELECT sno,cno
    -> FROM scores
    -> ORDER BY degree
    -> DESC
    -> LIMIT 0,1;
+-----+-------+
| sno | cno   |
+-----+-------+
| 103 | 3-105 |
+-----+-------+

11.查询‘3-105’号课程的平均分。

mysql> SELECT AVG(degree)
    -> FROM scores
    -> WHERE cno='3-105';
+-------------+
| AVG(degree) |
+-------------+
|    81.50000 |
+-------------+

*12.查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。

mysql> SELECT cno,AVG(degree)
    -> FROM scores
    -> WHERE cno LIKE '3%'
    -> GROUP BY cno
    -> HAVING COUNT(sno) >= 5;
+-------+-------------+
| cno   | AVG(degree) |
+-------+-------------+
| 3-105 |    81.50000 |
+-------+-------------+
1 row in set (0.01 sec)

SQL GROUP BY 语句

SQL HAVING 语句

HAVING 子句
在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用。

*13.查询最低分大于70,最高分小于90的Sno列。

mysql> SELECT sno
    -> FROM scores
    -> GROUP BY sno
    -> HAVING MAX(degree)<90 AND MIN(degree)>70;
+-----+
| sno |
+-----+
| 105 |
| 108 |
+-----+

*14.查询所有学生的Sname、Cno和Degree列。

mysql> SELECT sname,cno,degree
    -> FROM students INNER JOIN scores
    -> ON(students.sno = scores.sno)
    -> ORDER BY sname;
+-------+-------+--------+
| sname | cno   | degree |
+-------+-------+--------+
| 匡明  | 3-245 |   75.0 |
| 匡明  | 3-105 |   88.0 |
| 曾华  | 3-105 |   78.0 |
| 曾华  | 6-166 |   81.0 |
| 李军  | 3-105 |   64.0 |
| 李军  | 6-166 |   85.0 |
| 王丽  | 3-105 |   91.0 |
| 王丽  | 6-106 |   79.0 |
| 王芳  | 3-245 |   68.0 |
| 王芳  | 3-105 |   76.0 |
| 陆君  | 3-245 |   86.0 |
| 陆君  | 3-105 |   92.0 |
+-------+-------+--------+
12 rows in set (0.00 sec)

*内连接

这里使用的一个骚操作就是内连接,我们看看各种连接都是啥
图解SQL的各种连接

15.查询所有学生的Sno、Cname和Degree列。

mysql> SELECT sno, cname, degree
    -> FROM scores INNER JOIN courses
    -> ON(scores.cno = courses.cno)
    -> ORDER BY sno;
+-----+------------+--------+
| sno | cname      | degree |
+-----+------------+--------+
| 101 | 计算机导论 |   64.0 |
| 101 | 数据电路   |   85.0 |
| 103 | 操作系统   |   86.0 |
| 103 | 计算机导论 |   92.0 |
| 105 | 操作系统   |   75.0 |
| 105 | 计算机导论 |   88.0 |
| 107 | 计算机导论 |   91.0 |
| 108 | 计算机导论 |   78.0 |
| 108 | 数据电路   |   81.0 |
| 109 | 操作系统   |   68.0 |
| 109 | 计算机导论 |   76.0 |
+-----+------------+--------+
11 rows in set (0.04 sec)

*16.查询所有学生的Sname、Cname和Degree列。

这个有操作啊这个,sname只有students表里有,cname只有courses里面有,degree只有scores里面有,要把三个表连在一起,那么解题的思想就是先内联两个,形成一个表,再与另外一个内联。

那么目前的问题是,怎么联,谁先跟谁联?是不是已经把表忘记了?咱们先看看表

students:

+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 108 | 曾华  || 1977-09-01 00:00:00 | 95033 |
| 105 | 匡明  || 1975-10-02 00:00:00 | 95031 |
| 107 | 王丽  || 1976-01-23 00:00:00 | 95033 |
| 101 | 李军  || 1976-02-20 00:00:00 | 95033 |
| 109 | 王芳  || 1975-02-10 00:00:00 | 95031 |
| 103 | 陆君  || 1974-06-03 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+

cources:

+-------+------------+-----+
| cno   | cname      | tno |
+-------+------------+-----+
| 3-105 | 计算机导论 | 825 |
| 3-245 | 操作系统   | 804 |
| 6-166 | 数据电路   | 856 |
| 9-888 | 高等数学   | 100 |
+-------+------------+-----+

scores:

+-----+-------+--------+
| sno | cno   | degree |
+-----+-------+--------+
| 103 | 3-245 |   86.0 |
| 105 | 3-245 |   75.0 |
| 109 | 3-245 |   68.0 |
| 103 | 3-105 |   92.0 |
| 105 | 3-105 |   88.0 |
| 109 | 3-105 |   76.0 |
| 101 | 3-105 |   64.0 |
| 107 | 3-105 |   91.0 |
| 108 | 3-105 |   78.0 |
| 101 | 6-166 |   85.0 |
| 107 | 6-106 |   79.0 |
| 108 | 6-166 |   81.0 |
+-----+-------+--------+

要找联系,就是看看哪两个表之间有相同的列

students与scores之间有sno作为联系

scores与courses之间有cno作为联系

那么我们可以确定,scores作为关键的连接桥梁,我们需要让scores作为中转站

mysql> SELECT sname, cname, degree
    -> FROM scores INNER JOIN courses
    -> ON (scores.cno = courses.cno)
    -> INNER JOIN students
    -> ON (scores.sno = students.sno)
    -> ORDER BY sname;
+-------+------------+--------+
| sname | cname      | degree |
+-------+------------+--------+
| 匡明  | 操作系统   |   75.0 |
| 匡明  | 计算机导论 |   88.0 |
| 曾华  | 计算机导论 |   78.0 |
| 曾华  | 数据电路   |   81.0 |
| 李军  | 计算机导论 |   64.0 |
| 李军  | 数据电路   |   85.0 |
| 王丽  | 计算机导论 |   91.0 |
| 王芳  | 操作系统   |   68.0 |
| 王芳  | 计算机导论 |   76.0 |
| 陆君  | 操作系统   |   86.0 |
| 陆君  | 计算机导论 |   92.0 |
+-------+------------+--------+
11 rows in set (0.00 sec)

这里,我们让scores和courses先建立内联,然后再让这个表跟students内联,获得了结果。

当然我们也可以这样,让scores先和students建立内联,然后再跟courses表联结。

mysql> SELECT sname, cname, degree
    -> FROM students INNER JOIN scores
    -> ON (students.sno = scores.sno)
    -> INNER JOIN courses
    -> ON (scores.cno = courses.cno)
    -> ORDER BY sname;
+-------+------------+--------+
| sname | cname      | degree |
+-------+------------+--------+
| 匡明  | 操作系统   |   75.0 |
| 匡明  | 计算机导论 |   88.0 |
| 曾华  | 计算机导论 |   78.0 |
| 曾华  | 数据电路   |   81.0 |
| 李军  | 计算机导论 |   64.0 |
| 李军  | 数据电路   |   85.0 |
| 王丽  | 计算机导论 |   91.0 |
| 王芳  | 操作系统   |   68.0 |
| 王芳  | 计算机导论 |   76.0 |
| 陆君  | 操作系统   |   86.0 |
| 陆君  | 计算机导论 |   92.0 |
+-------+------------+--------+
11 rows in set (0.00 sec)

? 此问题存在疑惑,可跳过17.查询“95033”班所选课程的平均分。

首先我们看看原来的博文里面给的代码实例

mysql> SELECT cname,AVG(degree)
    -> FROM students INNER JOIN scores
    -> ON (students.sno = scores.sno)
    -> INNER JOIN courses
    -> ON (scores.cno = courses.cno)
    -> WHERE class = '95033'
    -> GROUP BY courses.cno
    -> ORDER BY cname;

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'classic_practice.courses.cname' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
下面是我找到的一个解答:

group by中的字段比较selelct中的字段差了一个month_id, 而正好是month_id报错。this is incompatible with sql_mode=only_full_group_by这句话提示了这违背了mysql的规则,only fully group by,也就是说在执行的时候先分组,根据查询的字段(select的字段)在分组的内容中取出,所以查询的字段全部都应该在group by分组条件内;一种情况例外,查询字段中如果含有聚合函数的字段不用包含在group by中,就像我上面的MAX(total_fee),至于为什么,我也不抬明白。
​ 后来发现Order by排序条件的字段也必须要在group by内,看此大神的博文解释之后豁然开朗,排序的字段也是从分组的字段中取出。 不明白的可以去看一下。

解决办法:select字段必须都在group by分组条件内(含有函数的字段除外)。(如果遇到order by也出现这个问题,同理,order by字段也都要在group by内)。
————————————————
原文链接:https://blog.csdn.net/u010429286/article/details/64444271

原来的博文下面有一个评论指出了这个问题并且给出了他的解答

mysql> SELECT AVG(degree)
    -> FROM scores WHERE
    -> sno IN (SELECT sno
    -> FROM students
    -> WHERE class = '95033')
    -> GROUP BY sno;
+-------------+
| AVG(degree) |
+-------------+
|    74.50000 |
|    85.00000 |
|    79.50000 |
+-------------+

这个是我的解法

mysql> SELECT cname,AVG(degree)
    -> FROM students INNER JOIN scores
    -> ON (students.sno = scores.sno)
    -> INNER JOIN courses
    -> ON (scores.cno = courses.cno)
    -> WHERE class = '95033'
    -> GROUP BY cname
    -> ORDER BY cname;
+------------+-------------+
| cname      | AVG(degree) |
+------------+-------------+
| 数据电路   |    83.00000 |
| 计算机导论 |    77.66667 |
+------------+-------------+

感觉哪里有些不对劲,我先不弄这个了,各位看官可以跳过这个,实在对不住了

18.假设使用如下命令建立了一个grade表:

CREATE TABLE grade(low TINYINT,upp TINYINT,rank CHAR(1));
INSERT INTO grade VALUES(90,100,'A');
INSERT INTO grade VALUES(80,89,'B');
INSERT INTO grade VALUES(70,79,'C');
INSERT INTO grade VALUES(60,69,'D');
INSERT INTO grade VALUES(0,59,'E');

现查询所有同学的Sno、Cno和rank列。

*首先,尽量别用rank,我创建表,一直提示我rank有错,查了才发现,rank是mysql的保留字

mysql> CREATE TABLE grade
    -> (low INT NOT NULL,
    -> upp INT NOT NULL,
    -> rank VARCHAR(1)
    -> )
    -> ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank VARCHAR(1)

—>问题答案

Above, an error is visible since we used reserved word as column name.
Let us first create a table and use backticks around “rank” to avoid error −

mysql> create table DemoTable1596
   -> (
   -> Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
   -> StudentName varchar(20),
   -> `rank` int
   -> );
Query OK, 0 rows affected (0.51 sec)

我是这么创建的,不用rank了,直接用g_rank

mysql> CREATE TABLE grade
    -> (low TINYINT NOT NULL,
    -> upp TINYINT NOT NULL,
    -> g_rank VARCHAR(1));
Query OK, 0 rows affected (0.14 sec)

mysql> INSERT INTO grade VALUES(90,100,'A');
Query OK, 1 row affected (0.02 sec)

mysql> INSERT INTO grade VALUES(80, 89, 'B');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO grade VALUES(70, 79, 'C');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO grade VALUES(60, 69, 'D');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO grade VALUES(0,59,'E');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM grade;
+-----+-----+--------+
| low | upp | g_rank |
+-----+-----+--------+
|  90 | 100 | A      |
|  80 |  89 | B      |
|  70 |  79 | C      |
|  60 |  69 | D      |
|   0 |  59 | E      |
+-----+-----+--------+
5 rows in set (0.00 sec)

然后就对应,sno和cno以及rank(g_rank)这三个列,出现在两个表中
一个scores,一个grade

mysql> SELECT sno, cno, g_rank
    -> FROM scores INNER JOIN grade
    -> ON (scores.degree>=grade.low AND scores.degree<=grade.upp)
    -> ORDER BY sno;
+-----+-------+--------+
| sno | cno   | g_rank |
+-----+-------+--------+
| 101 | 3-105 | D      |
| 101 | 6-166 | B      |
| 103 | 3-245 | B      |
| 103 | 3-105 | A      |
| 105 | 3-245 | C      |
| 105 | 3-105 | B      |
| 107 | 3-105 | A      |
| 107 | 6-106 | C      |
| 108 | 3-105 | C      |
| 108 | 6-166 | B      |
| 109 | 3-245 | D      |
| 109 | 3-105 | C      |
+-----+-------+--------+
12 rows in set (0.00 sec)

写了一下午了,着实顶不住了,这个先这样吧,明天继续写(二),而且这是我第一篇正式发布在CSDN上的文章,迫不及待想看看文章发布出来是啥样了

你可能感兴趣的:(数据库,sql,mysql)