Access 2010: Find students with select grades

2019-08-29 23:21发布

问题:

I have just made an Access 2010 database for analyzing students' grades in an exam. I was able to get grades for all students right. There are six subjects. Finding who got A in all six was easy, but what I want to do now is find who got A grade in any five out of six. Similarly, who missed A in any two subjects. Who failed in one subject? Two subjects? I just couldn't find a way to do it. Any help is greatly appreciated.

PS: What I have on my mind is a form with two text or combo boxes where you put Grades in one and Subjects in the other to get the result. For example, you select B in the first and Three in the second to get the list of students who got B grade in any three subjects. Only I don't know how it can be done.

What I did to find students who got A for all subjects: Used A as the criteria in the query.

SELECT 
    exam_grade.SNAME, 
    exam_grade.[Language Score], 
    exam_grade.[English Grade], 
    exam_grade.[Language Grade], 
    exam_grade.[Phy Grade], 
    exam_grade.[Chem Grade], 
    exam_grade.[Bio Grade], 
    exam_grade.[Math Grade], 
    exam_grade.DIVISION, 
    exam_grade.Result
FROM exam_grade
WHERE (((exam_grade.[English Grade])="A") 
    AND ((exam_grade.[Language Grade])="A") 
    AND ((exam_grade.[Phy Grade])="A") 
    AND ((exam_grade.[Chem Grade])="A") 
    AND ((exam_grade.[Bio Grade])="A") 
    AND ((exam_grade.[Math Grade])="A"));

回答1:

As you're storing each subject in its own column (rather than being decomposed into rows) you'll always have to specify every subject in every query. This does make the queries more conceptually simpler as then it's just a matter of doing boolean logic:

Students who had any 'A' grade:

SELECT 
    exam_grade.SNAME, 
    exam_grade.[Language Score], 
    exam_grade.[English Grade], 
    exam_grade.[Language Grade], 
    exam_grade.[Phy Grade], 
    exam_grade.[Chem Grade], 
    exam_grade.[Bio Grade], 
    exam_grade.[Math Grade], 
    exam_grade.DIVISION, 
    exam_grade.Result
FROM
    exam_grade
WHERE
    exam_grade.[English Grade]  = "A" OR
    exam_grade.[Language Grade] = "A" OR
    exam_grade.[Phy Grade]      = "A" OR
    exam_grade.[Chem Grade]     = "A" OR
    exam_grade.[Bio Grade]      = "A" OR
    exam_grade.[Math Grade]     = "A"

Students failed any subject:

....
WHERE
    exam_grade.[English Grade]  = "F" OR
    exam_grade.[Language Grade] = "F" OR
    exam_grade.[Phy Grade]      = "F" OR
    exam_grade.[Chem Grade]     = "F" OR
    exam_grade.[Bio Grade]      = "F" OR
    exam_grade.[Math Grade]     = "F"

...and so on for each query you have.

You can simplify this by adopting a decomposed database structure, like so:

CREATE TABLE Students (
    StudentId bigint PRIMARY KEY IDENTITY(1,1),
    FirstName nvarchar(50),
    LastName nvarchar(50)
)

CREATE TABLE Subjects (
    SubjectId bigint PRIMARY KEY IDENTITY(1,1),
    Name nvarchar(50)
)

CREATE TABLE Results (
    StudentId bigint,
    SubjectId bigint, -- composite key with StudentId, assuming no student can take the same subject twice
    Grade     char(1) -- though storing the numeric score would be more flexible
)

Then to find students that failed any subject (for example)

SELECT
    Students.FirstName,
    Students.LastName,
    FailedResults.FailedCount
FROM

    (SELECT
        Results.StudentId,
        COUNT(*) As FailedCount
    FROM
        Results
        INNER JOIN Subjects ON Results.SubjectId = Subjects.SubjectId
    WHERE
        Results.Grade = 'F'
    GROUP BY
        Results.StudentId
    ) As FailedResults

    INNER JOIN Students ON FailedResults.StudentId = Students.StudentId

this way you just add rows to the Subjects and Results table without needing to add columns and re-edit your queries.



回答2:

According to your example and what do you want to do and just following your logic because I think that you have an algorithm for resolve, I can suggest this:

First, you need to put a value for each grade, for example I simplify the grades in three.

POSIBLE GRADES A,B,C WITH THEIR VALUES

  • A = 3
  • B = 2
  • C = 1

Then you need to sum the changed values, like this:

 SELECT * FROM
    (SELECT id_student,
        CONVERT(INT,CASE language_grade
            WHEN 'A' THEN '3' 
            WHEN 'B' THEN '2' 
            WHEN 'C' THEN '1'
        END)
        +
        CONVERT(INT,CASE english_grade
            WHEN 'A' THEN '3' 
            WHEN 'B' THEN '2' 
            WHEN 'C' THEN '1'
        END)
        +
        CONVERT(INT,CASE chem_grade
            WHEN 'A' THEN '3' 
            WHEN 'B' THEN '2' 
            WHEN 'C' THEN '1'
        END) AS RESULT
 FROM test) TB
 WHERE RESULT >= 6

Well, following your form example, you can select 'A' grade in first combobox, Then you put number 2, this mean that you want at least 2 subjects with at least 'A' in grade, if you that you grade 'A' has value of three, you can multiply that value to the number put in the second textbox, and that result is 6, so you can deduce else rigth? ;). (Dont forget to use equal,greater than or equal, etc, to change your query.)

PSDT

I know that this isn't access sintax, but if you can "translate" to access sintax, this will work.