How can I show the subjects as column headers, as well as the student name and total mark

谁说胖子不能爱 提交于 2020-01-06 02:31:25

问题


I have 4 tables in my Microsoft SQL Server Db: Subject, Student, Exam and ExamResults.

Subject table columns: SubjectID,SubjectName

Student table columns: StudentID,Fname,Lname

Exam table columns: ExamID,ExamDate,ExamPeriod,Class

ExamResults column: ExamResultID,ExamID,StudentID,SubjectID,Result

I am using the following query to get the results on a winforms datagridview (which I'm hosting on a wpf application):

"SELECT SubjectName, Subject.SubjectID,Result, Fname, Lname FROM Subject "
+"LEFT JOIN ExamResults ON Subject.SubjectID=ExamResults.SubjectID "
+"LEFT JOIN Exam ON ExamResults.ExamID=Exam.ExamID "
+"LEFT JOIN Student on ExamResults.StudentID=Student.StudentID "
+"WHERE Exam.Class=@Class";

I'm getting a result like this:

SubjectName | SubjectID | Result |  Fname  | Lname
------------+-----------+--------+---------+----------
English     |     1     |   100  | Earnest | Baker
Mathematics |     2     |    35  | Earnest | Baker
French      |     6     |    75  | Earnest | Baker
English     |     1     |    56  |  House  | Richards
Geography   |     5     |    35  |  House  | Richards
French      |     6     |    75  |  House  | Richards
English     |     1     |    86  |  Jacob  | Jake
Mathematics |     2     |    37  |  Jacob  | Jake
Literature  |     8     |    75  |  Jacob  | Jake

Out of the 5 subjects,what I really want to achieve is to have the table use the following column headers and use that format:

 Fname  |   Lname  | English | Mathematics | Geography | Literature | French | TotalScore
 -------+----------+---------+-------------+-----------+------------+--------+-------------
Earnest |   Baker  |   100   |     35      |      -    |     -      |   75   |     210    
 House  | Richards |    56   |      -      |     35    |     -      |   75   |     166
 Jacob  |    Jake  |    86   |     37      |      -    |     75     |    -   |     198 

I intend to use Subject.subjectID for other use, not to display it on the datagridview, so assume it's hidden.

Is this possible given the the way I've created my tables, or do I need to change the tables, or is it the query that needs to change. Or maybe i need to display it in some way on the datagridview? Please help me because I can't find a solution.


回答1:


You can achieve this using PIVOT:

SELECT  pvt.Forename,
        pvt.Surname,
        pvt.[English], 
        pvt.[Mathematics], 
        pvt.[Geography], 
        pvt.[Literature], 
        pvt.[French],
        TotalScore = ISNULL(pvt.[English], 0) + ISNULL(pvt.[Mathematics], 0) + ISNULL(pvt.[Geography], 0) + ISNULL(pvt.[Literature], 0) + ISNULL(pvt.[French], 0)
FROM    (   SELECT  s.SubjectName, er.Result, su.Fname, su.Lname 
            FROM    Subject AS s
                    INNER JOIN ExamResults AS er
                        ON s.SubjectID = er.SubjectID
                    INNER JOIN Exam AS e
                        ON er.ExamID = e.ExamID
                    LEFT JOIN Student AS su
                        ON er.StudentID = su.StudentID
            WHERE   e.Class = @Class
        ) AS e
        PIVOT 
        (   MAX([Result]
            FOR [Subject] IN ([English], [Mathematics], [Geography], [Literature], [French])
        ) AS pvt;

Or a conditional aggregate:

SELECT  su.Fname, 
        su.Lname ,
        [English] = MAX(CASE WHEN s.SubjectName = 'English' THEN er.Result END), 
        [Mathematics] = MAX(CASE WHEN s.SubjectName = 'Mathematics' THEN er.Result END), 
        [Geography] = MAX(CASE WHEN s.SubjectName = 'Geography' THEN er.Result END), 
        [Literature] = MAX(CASE WHEN s.SubjectName = 'Literature' THEN er.Result END), 
        [French] = MAX(CASE WHEN s.SubjectName = 'French' THEN er.Result END), 
        TotalScore = SUM(er.Result)
FROM    Subject AS s
        INNER JOIN ExamResults AS er
            ON s.SubjectID = er.SubjectID
        INNER JOIN Exam AS e
            ON er.ExamID = e.ExamID
        LEFT JOIN Student AS su
            ON er.StudentID = su.StudentID
WHERE   e.Class = @Class
GROUP BY su.Fname, su.Lname;


来源:https://stackoverflow.com/questions/28233022/how-can-i-show-the-subjects-as-column-headers-as-well-as-the-student-name-and-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!