0

我有一个任务,我有点挂在 SQL Server 上,想知道是否有人可以提供帮助。

任务:
在数据库中,我需要创建一个名为 的存储过程ClassRegistration。此存储过程的结果集的列需要如下所示:

  1. [Class]– 要教授的班级名称
  2. [Teacher Name]- 授课人的姓名
  3. [Registrations]- 已注册上课的学生人数
  4. [Number Paid]- 已支付课程费用的学生人数

表:

  1. [Teacher]: Teacher_ID(PK),TeacherName
  2. [Class]: Class_ID(PK), ClassName, Teacher_ID(FK)
  3. [ClassRegistration] Student_ID(FK), Class_ID(FK),HasPaidFees
  4. [Student] Student_ID(PK),StudentName

即使没有人注册,学院也需要了解每一门课程。

到目前为止我的 SQL:

Create  PROCEDURE ClassRegistration
AS
SELECT DISTINCT 
    c.ClassName, 
    t.TeacherName, 
    COUNT(cr.Student_ID) As Registrations, 
    COUNT(case when cr.HasPaidFees = 1 then 1 else null end) As NumberPaid
FROM 
    Class As c, 
    Teacher As t, 
    ClassRegistration As cr, 
    Student As s
WHERE
    (c.Class_ID = cr.Class_ID) 
AND (cr.Student_ID = s.Student_ID)
GROUP BY c.ClassName, t.TeacherName

我可以很好地创建存储过程,但输出看起来不正确,任何帮助将不胜感激:)。

4

2 回答 2

1

如果您需要在没有注册的情况下查找课程,则需要使用left outer join

SELECT  Distinct c.ClassName, t.TeacherName, COUNT(cr.Student_ID) As Registrations, COUNT(case when cr.HasPaidFees = 1 then 1 else null end) As NumberPaid
FROM    Class As c
INNER JOIN Teacher As t
on c.Teacher_ID = t.Teacher_ID
LEFT OUTER JOIN ClassRegistration As cr
ON (c.Class_ID = cr.Class_ID)
INNER JOIN Student As s
ON  (cr.Student_ID = s.Student_ID)
GROUP BY c.ClassName, t.TeacherName

(请注意,我已将您的其他联接重写为INNER JOIN

于 2012-09-23T18:11:20.243 回答
1

没有理由加入 Student,您有 4 个表,但只有 2 个加入条件。这是使用旧的table,table连接语法而不是正确的显式连接的缺陷之一。我也:

  • 首先列出您的“内部”表格
  • dbo.为表引用添加前缀
  • 添加SET NOCOUNT ON到程序中
  • 删除了不必要的DISTINCT
  • 简化CASE表达式
CREATE PROCEDURE dbo.ClassRegistration
AS
BEGIN
  SET NOCOUNT ON;

  SELECT c.ClassName, t.TeacherName, 
    COUNT(cr.Student_ID) As Registrations, 
    COUNT(NULLIF(cr.HasPaidFees, 0)) As NumberPaid
  FROM dbo.Class As c
  INNER JOIN dbo.Teacher As t
  ON t.Teacher_ID = c.Teacher_ID
  LEFT OUTER JOIN dbo.ClassRegistration As cr
  ON c.Class_ID = cr.Class_ID
  GROUP BY c.ClassName, t.TeacherName;
END
GO
于 2012-09-23T18:12:26.637 回答