【数据库】查询语句

来源:互联网 发布:国际象棋在线对弈软件 编辑:程序博客网 时间:2024/06/08 06:52

隐式连接与显式连接

隐式连接:

SELECT CourseName, TeacherName

FROM Courses 

INNER JOIN Teachers

ON Courses.TeacherID = Teahcer.TeacherID


等价于显式连接

SELECT CourseName, TeacherName

FROM Courses, Teachers

WHERE Courses.TeacherID = Teahcer.TeacherID

很明显显式连接更好用


非规范化和规范化数据库

规范化数据库的设计目标是将冗余降到最低,而非规范化数据库则是为了优化读取时间。

例如Courses和Teachers的数据,Courses可能含有TeacherID列,只是指向Teachers的外键。这么做的好处之一是,关于教师的信息(姓名,住址等)在数据库中只有一份。缺点是大量常用的查询需要执行开销很大的链接操作。

那么我们可以存储冗余数据,是数据库非规范化。例如,如果预计到这类查询会频繁执行,可以将教师姓名存到Courses表中,非规范化通常用于构建高可扩展性系统。


SQL语句

一个数据库的简单结构如下:

Courses: CourseID, CourseName, TeacherID

Teachers: TeacherID, TeacherName

Students: StudentID, StudentName

StudentCourses: CourseID, StudentID


问题1:实现一个查询,列出所有学生,以及每个学生选修了几门课程

SELECT Students.StudentName,Students.StudentID

COUNT(StudentCourses.CourseID) AS [Cnt]

FROM Students LEFT JOIN StudentCourses

ON Students.StudentID = StudentCourses.StudentID 

GROUP BY Students.StudentID, Students.StudentName

1. 有可能有学生一门课都没有选,所以要用left join而不是inner join。

LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。

SELECT column_name(s)FROM table_name1LEFT JOIN table_name2 ON table_name1.column_name=table_name2.column_name
2. 如果只按照StudentID分组,数据库不知道该返回哪个StudentName,所以还要将StudentName也加入到GROUP BY字句里


问题2: 教师班级规模

实现一个查询,取得一份所有教师的列表,以及每位教师要教多少学生。如果一位教师给某个学生教授两门课程,那么这个学生就要计入两次。

根据教师教授的学生人数,将列表结果从大到小排列。


先取得一份teahcerID列表,以及有多少学生跟各个TeacherID有关联:

SELECT Courses.TeacherID, COUNT( StudentCourses.StudentID ) AS [Number]

FROM CoursesStudentCourses

WHERE Courses.CourseIDStudentCourses.CourseID

GOURP BY Courses.TeacherID

然后将上面的结果与包含所有教师的列表相连接

SELECT TeacherName, isnull(StudentSize.Number, 0)

FROM Teachers LEFT JOIN

SELECT Courses.TeacherID, COUNT( StudentCourses.StudentID ) AS [Number]

FROM Courses, StudentCourses

WHERE Courses.CourseID = StudentCourses.CourseID

GOURP BY Courses.TeacherID )

ON Teachers.TeacherID = StudentSize.TeacherID

ORDERBY StudentSize.TeacherID DESC


0 0
原创粉丝点击