使用唯一记录作为表头

时间:2014-01-25 15:38:47

标签: sql database ms-access

我有这3张桌子

  1. 学生表[student_id(pk), firstname, lastname]
  2. 主题表[subject_id(pk), subject_title]
  3. 成绩表[score_id(pk), score, student_id(fk), subject_id(fk)]
  4. 有没有办法可以提出一个查询,以便我可以用这种形式将它显示在一个表格中:

    _______________________________________
    |学生姓名|主题1 |主题2 |主题3 |
    -------------------------------------------------- ------------
    | __student1 ___ | ___ 98 ____ | ___ 92 ___ | ___ 97 ___ |
    | __student2 ___ | ___ 93 ____ | ___ 91 ___ | ___ 95 ___ |
    | __student3 ___ | ___ 95 ____ | ___ 92 ___ | ___ 97 ___ |
    | __student4 ___ | ___ 97 ____ | ___ 95 ___ | ___ 91 ___ |

    学生姓名来自学生表
    主题1,主题2,主题来自主题表的唯一记录
    然后
    成绩表中的成绩

    是否可能或我的数据库架构设计不好?

    这是表记录

    Student table
    |student_id | student_name|
    |     1     |   student1  |
    |     2     |   student2  |
    
    Subject table
    |subject_id | subject_name|
    |     1     |   subject1  |
    |     2     |   subject2  |
    |     3     |   subject3  | 
    
    Grade table
    | grade_id | grade | subject_id | student_id |
    |     1    |   87  |     1      |     1      |
    |     2    |   87  |     2      |     1      |
    |     3    |   87  |     3      |     1      |
    |     4    |   87  |     1      |     2      |
    |     5    |   87  |     2      |     2      |
    |     6    |   87  |     3      |     2      |
    

2 个答案:

答案 0 :(得分:1)

通用SQL方法是使用条件聚合:

select s.studentName,
       max(case when s.subjectName = 'subject1' then g.grade end) as Subject1,
       max(case when s.subjectName = 'subject2' then g.grade end) as Subject2,
       max(case when s.subjectName = 'subject3' then g.grade end) as Subject3
from (students s join
      grades g
      on s.student_id = g.student_id
     ) join
     subjects su
     on g.subject_id = su.subject_id
group by s.studentid, s.studentName;

多个数据库也支持pivot语法来执行此操作。

编辑:

Access查询是:

select s.studentName,
       max(iif(s.subjectName = 'subject1', grade,  NULL)) as Subject1,
       max(iif(s.subjectName = 'subject2', grade,  NULL)) as Subject2,
       max(iif(s.subjectName = 'subject3', grade,  NULL)) as Subject3
from students s inner join
     grades g
     on s.student_id = g.student_id inner join
     subjects su
     on g.subject_id = su.subject_id
group by s.studentid, s.studentName;

答案 1 :(得分:0)

假设你只有3个科目,这是最简单的方法。

;WITH Student(student_id, student_name) AS
(
    SELECT 1, 'student1'    UNION ALL 
    SELECT 2, 'student2' 
)
,[Subject] (subject_id, subject_name) AS
(
    SELECT 1, 'subject1' UNION ALL
    SELECT 2, 'subject2' UNION ALL
    SELECT 3, 'subject3'
)
,Grade (grade_id, grade, subject_id, student_id) AS
(
    SELECT 1, 87, 1, 1 UNION ALL
    SELECT 2, 87, 2, 1 UNION ALL
    SELECT 3, 87, 3, 1 UNION ALL
    SELECT 4, 87, 1, 2 UNION ALL
    SELECT 5, 87, 2, 2 UNION ALL
    SELECT 6, 87, 3, 2 
)
SELECT   S.student_name
        ,Subject1   = G1.grade
        ,Subject2   = G2.grade
        ,Subject3   = G3.grade
FROM Student    S
JOIN Grade      G1  ON S.student_id = G1.student_id AND G1.subject_id = 1
JOIN Grade      G2  ON S.student_id = G2.student_id AND G2.subject_id = 2
JOIN Grade      G3  ON S.student_id = G3.student_id AND G3.subject_id = 3

PIVOT方法;

;WITH Student(student_id, student_name) AS
(
    SELECT 1, 'student1'    UNION ALL 
    SELECT 2, 'student2' 
)
,[Subject] (subject_id, subject_name) AS
(
    SELECT 1, 'subject1' UNION ALL
    SELECT 2, 'subject2' UNION ALL
    SELECT 3, 'subject3'
)
,Grade (grade_id, grade, subject_id, student_id) AS
(
    SELECT 1, 87, 1, 1 UNION ALL
    SELECT 2, 87, 2, 1 UNION ALL
    SELECT 3, 87, 3, 1 UNION ALL
    SELECT 4, 87, 1, 2 UNION ALL
    SELECT 5, 87, 2, 2 UNION ALL
    SELECT 6, 87, 3, 2 
)
,PrePivot AS 
(
    SELECT   S.student_name
            ,ST.subject_name
            ,G.Grade
    FROM Student    S
    JOIN Grade      G   ON S.student_id = G.student_id
    JOIN [Subject]  ST  ON G.subject_id = ST.subject_id
)
SELECT *
FROM PrePivot
PIVOT
(
    MAX(Grade)
    FOR subject_name IN (subject1, subject2, subject3)
)PVT