我如何将主题显示为列标题,以及学生姓名和总标记 [英] How can I show the subjects as column headers, as well as the student name and total mark

查看:89
本文介绍了我如何将主题显示为列标题,以及学生姓名和总标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Microsoft SQL Server Db中有4个表:主题,学生,考试和考试结果。



主题表列: SubjectID,SubjectName



学生表列: StudentID,Fname,Lname



考试表列: ExamID,ExamDate,ExamPeriod,Class



ExamResults列: ExamResultID,ExamID,StudentID,SubjectID,Result / p>

我正在使用以下查询来获取winforms datagridview(我在wpf应用程序上托管)的结果:

 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;

我得到这样的结果:

  SubjectName | SubjectID |结果| Fname | Lname 
------------ + ----------- + -------- + --------- + - ---------
英文| 1 | 100 |认真的|贝克
数学| 2 | 35 |认真的|贝克
法语| 6 | 75 |认真的|贝克
英文| 1 | 56 |房子|理查兹
地理| 5 | 35 |房子|理查兹
法语| 6 | 75 |房子|理查兹
英文| 1 | 86 |雅各布| Jake
数学| 2 | 37 |雅各布| Jake
文学| 8 | 75 |雅各布| Jake

在5个科目中,我真正想要实现的是让表使用以下列标题并使用该格式:

  Fname | Lname |英文|数学|地理|文学|法语| TotalScore 
------- + ---------- + --------- + ------------- + - --------- + ------------ + -------- + -------------
认真|贝克| 100 | 35 | - | - | 75 | 210
房屋|理查兹56 | - | 35 | - | 75 | 166
雅各布|杰克| 86 | 37 | - | 75 | - | 198

我打算使用Subject.subjectID进行其他使用,不要在datagridview上显示它,所以假设它被隐藏。



这可能是因为我创建了表的方式,或者我需要更改表,还是需要查询更改。或者也许我需要在datagridview上以某种方式显示它?请帮助我,因为找不到解决方案。

解决方案

您可以使用 PIVOT

  SELECT pvt.Forename,
pvt.Surname,
pvt。[English],
pvt。[数学],
pvt。[地理],
pvt。[文学],
pvt。[法语],
总分= ISNULL(pvt。[英文] ,0)+ ISNULL(pvt。[数学],0)+ ISNULL(pvt。[Geography],0)+ ISNULL(pvt。[文献],0)+ ISNULL(pvt。[法语],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考试作为e
打开er.ExamID = e.ExamID
LEFT JOIN学生AS su
ON er.StudentID = su.StudentID
WHERE e.Class = @Class
)AS e
PIVOT
(MAX([Result]
FOR [Subject] IN([英文],[数学],[地理],[文学],[法文])
)AS pvt;

或条件聚合:

  SELECT su.Fname,
su.Lname,
[英文] = MAX(CASE WHEN s.SubjectName ='English'THEN er.Result END),
[数学] = MAX(CASE WHEN s.SubjectName ='Mathematics'THEN er.Result END),
[Geography] = MAX(CASE WHEN s.SubjectName ='Geography'THEN er.Result END),
[文献] = MAX(CASE WHEN s.SubjectName ='Literature'THEN er.Result END),
[法语] = 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考试AS e
ON er.ExamID = e.ExamID
LEFT JOIN学生AS su
ON er.StudentID = su.StudentID
WHERE e.Class = @Class
GROUP BY su.Fname,su.Lname;


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.

解决方案

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;

这篇关于我如何将主题显示为列标题,以及学生姓名和总标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆