### SQL查询语句精炼知识点解析
#### 一、知识点概览
本文将对一系列SQL查询练习进行深入解析,涵盖常见的SQL查询技巧,包括子查询、连接查询、聚合函数等高级用法。通过这些练习,我们可以更好地理解如何利用SQL解决实际问题。
#### 二、详细解析
**1. 查询“001”课程比“002”课程成绩高的所有学生的学号**
此查询通过使用两个子查询来比较不同课程的成绩,找出成绩较高的学生。
```sql
SELECT A.S#
FROM (SELECT S#, Score FROM SC WHERE C# = '001') A,
(SELECT S#, Score FROM SC WHERE C# = '002') B
WHERE A.Score > B.Score AND A.S# = B.S#;
```
**2. 查询平均成绩大于60分的同学的学号和平均成绩**
这里使用`GROUP BY`和`HAVING`子句来计算每个学生的平均成绩,并筛选出平均成绩高于60分的学生。
```sql
SELECT S#, AVG(Score)
FROM SC
GROUP BY S#
HAVING AVG(Score) > 60;
```
**3. 查询所有同学的学号、姓名、选课数、总成绩**
该查询使用左连接(`LEFT OUTER JOIN`)来确保所有学生的信息都被包含进来,并使用`COUNT`和`SUM`函数统计每位学生的选课数量和总成绩。
```sql
SELECT Student.S#, Student.Sname, COUNT(SC.C#), SUM(Score)
FROM Student LEFT OUTER JOIN SC ON Student.S# = SC.S#
GROUP BY Student.S#, Sname;
```
**4. 查询姓“李”的老师的个数**
这里使用`LIKE`操作符来匹配以“李”开头的名字,并通过`DISTINCT`去除重复项后计数。
```sql
SELECT COUNT(DISTINCT Tname)
FROM Teacher
WHERE Tname LIKE '李%';
```
**5. 查询没学过“叶平”老师课的同学的学号、姓名**
这个查询首先找出所有学过叶平老师课程的学生学号,然后通过`NOT IN`操作找到未出现在该列表中的学生。
```sql
SELECT Student.S#, Student.Sname
FROM Student
WHERE S# NOT IN (
SELECT DISTINCT(SC.S#)
FROM SC, Course, Teacher
WHERE SC.C# = Course.C# AND Teacher.T# = Course.T# AND Teacher.Tname = '叶平'
);
```
**6. 查询学过“001”并且也学过编号“002”课程的同学的学号、姓名**
这里使用`EXISTS`子查询来判断学生是否同时学过两个指定的课程。
```sql
SELECT Student.S#, Student.Sname
FROM Student, SC
WHERE Student.S# = SC.S# AND SC.C# = '001' AND EXISTS (
SELECT *
FROM SC AS SC_2
WHERE SC_2.S# = SC.S# AND SC_2.C# = '002'
);
```
**7. 查询学过“叶平”老师所教的所有课的同学的学号、姓名**
这个查询较为复杂,涉及到多表连接和子查询。首先找出叶平老师教授的所有课程,然后通过内连接和`GROUP BY`找到所有选修了这些课程的学生。
```sql
SELECT S#, Sname
FROM Student
WHERE S# IN (
SELECT S#
FROM SC, Course, Teacher
WHERE SC.C# = Course.C# AND Teacher.T# = Course.T# AND Teacher.Tname = '叶平'
GROUP BY S#
HAVING COUNT(SC.C#) = (
SELECT COUNT(C#)
FROM Course, Teacher
WHERE Teacher.T# = Course.T# AND Tname = '叶平'
)
);
```
**8. 查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名**
这里通过自连接的方式,对比同一学生在两个不同课程的成绩。
```sql
SELECT S#, Sname
FROM (
SELECT Student.S#, Student.Sname, Score, (
SELECT Score
FROM SC AS SC_2
WHERE SC_2.S# = Student.S# AND SC_2.C# = '002'
) AS Score2
FROM Student, SC
WHERE Student.S# = SC.S# AND C# = '001'
) AS S_2
WHERE Score2 < Score;
```
**9. 查询所有课程成绩小于60分的同学的学号、姓名**
此查询使用`NOT IN`来找出成绩均低于60分的学生。
```sql
SELECT S#, Sname
FROM Student
WHERE S# NOT IN (
SELECT Student.S#
FROM Student, SC
WHERE S.S# = SC.S# AND Score > 60
);
```
**10. 查询没有学全所有课的同学的学号、姓名**
这里通过计算每位学生的选课数与所有课程的数量进行对比,找出未选全课程的学生。
```sql
SELECT Student.S#, Student.Sname
FROM Student, SC
WHERE Student.S# = SC.S#
GROUP BY Student.S#, Student.Sname
HAVING COUNT(C#) < (SELECT COUNT(C#) FROM Course);
```
**11. 查询至少有一门课与学号为“1001”的同学所学相同的同学的学号和姓名**
此查询通过子查询找到学号为“1001”的学生所选课程的课程编号,然后找出至少选修了一门相同课程的其他学生。
```sql
SELECT S#, Sname
FROM Student, SC
WHERE Student.S# = SC.S# AND C# IN (
SELECT C#
FROM SC
WHERE S# = '1001'
);
```
**12. 查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名**
该查询旨在找出所有选修了与学号为“001”的学生相同课程的其他学生。需要注意的是,原始代码片段不完整,因此这里提供了一个完整的解决方案。
```sql
SELECT DISTINCT SC.S#, Sname
FROM Student, SC
WHERE Student.S# = SC.S# AND C# IN (
SELECT C#
FROM SC
WHERE S# = '001'
);
```
### 结论
通过上述SQL查询练习的解析,我们可以看到SQL的强大功能以及在处理复杂数据时的灵活性。掌握这些技巧对于数据库开发者和管理员来说是非常重要的。希望这些例子能够帮助大家更好地理解和应用SQL语言。
由于没有提供具体的数据表和字段信息,以下是一般的SQL语句示例:
SELECT COUNT(*) FROM teachers WHERE last_name = '李';
这条SQL语句将查询姓“李”的老师的个数,假设数据表名为“teachers”,并且该表中包含“last_name”字段,该字段记录了老师的姓。