开发者

Is it possible to use a aggregate in an aggregate to get a specific single value?

I have been playing around with code for a while now, and I have come across a problem where I must get the amount of certain fields where the average is above a certain amount , grouped by two fields from different tables

Here is my Code and expectations

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

This sends me back the rows containing the course name, the student's name, and the amount of percentages above 80%.

This counts for me as "the amounts of students that passed the course". I would Like to know how to force this query to give me the amount of students who have passed the course in stead of the amount of modules the student has passed and if it is possible

EDIT 1:

STUDENT LAYOUT

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)
      开发者_StackOverflow      ,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);   


If they need to pass by average 80% across all modules.

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 

If they need to pass each module by 80% to pass the course then

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 

This is untested, let me know any errors or paste incorrect output and expected output.


It looks like you want the number of students that passed each course? If so wouldn't you just need to group by C.Course and then have a Count(S.Name) as NumWhoPassed for the display?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜