是否可以在聚合中使用聚合来获取特定的单个值?

时间:2011-10-10 18:15:22

标签: tsql

我一直在玩代码一段时间了,我遇到了一个问题,我必须得到平均值高于一定数量的某些字段的数量,按不同表中的两个字段分组

这是我的准则和期望

SELECT C.Course,S.Name, COUNT(*) as Average FROM Students S
INNER JOIN Student_Modules SM ON
SM.StudentID = S.ID
INNER JOIN Courses_Template C
ON C.ID = SM.CourseID
Group by C.Course,S.Name
Having AVG(SM.Percentage_Obtained) > 80

这会将包含课程名称,学生姓名和百分比超过80%的行发回给我。

这对我来说是“通过课程的学生数量”。我想知道如何强制这个查询给我通过课程的学生数量,而不是学生已经通过的模块数量,如果可能的话

编辑1:

学生布局

CREATE TABLE Students
            (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
            ,StudentNumber VARCHAR(20)
            ,Name VARCHAR(40)
            ,Surname VARCHAR(40)
            ,Student_ID VARCHAR(13)
            ,Languages VARCHAR(200)
            ,[Address] Varchar (512)
            ,Contact_Number varchar(20)
            ,Email Varchar (150)
            ,Days_Absent INT
            ,Student_Web_Username varchar(40)
            ,Student_Web_Password varchar(MAX)
            ,BranchID int 
            ,Constraint FKStudentBranch FOREIGN KEY (BranchID) REFERENCES Branches(ID)
            ,CONSTRAINT Unq_StudentNumber UNIQUE (StudentNumber)
            ,CONSTRAINT Unq_Student_ID UNIQUE (Student_ID)); 

STUDENT_MODULE LAYOUT

CREATE TABLE Student_Modules
            (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
            ,ModuleID INT
            ,StudentID INT
            ,CourseID INT
            ,Percentage_Obtained INT Check (Percentage_Obtained >= -1 AND Percentage_Obtained <= 100)
            ,CONSTRAINT FKStudentModulesChosen FOREIGN KEY (ModuleID) REFERENCES Modules_Template(ID) ON DELETE CASCADE
            ,CONSTRAINT FKStudentModules FOREIGN KEY (StudentID) REFERENCES Students(ID) ON DELETE CASCADE);    

COURSES_TEMPLATE LAYOUT

CREATE TABLE COURSES_TEMPLATE
        (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED 
        ,Course VARCHAR(40)
        ,Price SMALLMONEY CHECK(Price > 0)
        ,BranchID INT
        ,CONSTRAINT FKCourseBranches FOREIGN KEY (BranchID) REFERENCES Branches(ID) ON DELETE CASCADE);   

2 个答案:

答案 0 :(得分:0)

看起来你想要通过每门课程的学生人数?如果是这样,你不需要按照C.Course进行分组,然后将Count(S.Name)作为NumWhoPassed用于显示?

答案 1 :(得分:0)

如果他们需要在所有模块中平均通过80%。

SELECT C.Course, COUNT(*) as [Average] 
FROM Students S 
INNER JOIN Student_Modules SM ON S.ID = SM.StudentID 
INNER JOIN Courses_Template C ON SM.CourseID = C.ID 
INNER JOIN (
    SELECT SM.StudentID, SM.CourseID 
    FROM Student_Modules SM 
    Group by SM.StudentID, SM.CourseID 
    Having AVG(SM.Percentage_Obtained) > 80
) Pass ON SM.StudentID = Pass.StudentID AND SM.CourseID = Pass.CourseID 
GROUP BY C.Course 

如果他们需要通过每个模块80%才能通过课程

SELECT C.Course, COUNT(*) as [Average] 
FROM Students S 
INNER JOIN Student_Modules SM ON S.ID = SM.StudentID 
INNER JOIN Courses_Template C ON SM.CourseID = C.ID 
LEFT OUTER JOIN (
    SELECT DISTINCT SM.StudentID, SM.CourseID 
    FROM Student_Modules SM 
    WHERE SM.Percentage_Obtained <= 80
) as NotPass ON SM.StudentID = NotPass.StudentID AND SM.CourseID = NotPass.CourseID 
WHERE NotPass.StudentID IS NULL 
GROUP BY C.Course 

这是未经测试的,让我知道任何错误或粘贴错误的输出和预期的输出。