一行中的多行作为列(mysql)

时间:2013-05-18 09:00:41

标签: mysql sql

我有学校数据库,我需要为所有学生显示报告,每个学生都有多个科目和学位

SELECT grades.student_id,   
     grades.class_id,   
     grades.course_id,   
     grades.general_total
     grades.activity
FROM grades 
WHERE  grades.class_id = 17 

我的输出就像它

student_id      class_id    course_id   general_total     activity  ....
=================================================================================
330             17              1               15         55
330             17              3               22         44
331             17              1               11         13
331             17              3               12         14
=================================================================================

我需要输出

--------------------------------------------------------------------
student_id  class_id    general_total for course 1       general_total for course 3            activity for course1          activity for course3     ....
=================================================================================================================================================
330             17              15                               22                                   55                           44
331             17              11                               12                                   13                           14
=================================================================================================================================================

这意味着我需要向所有学生展示他所有课程的学位

2 个答案:

答案 0 :(得分:1)

试试这个:

SELECT student_id, class_id
,SUM(CASE WHEN course_id = 1 
          THEN general_total ELSE 0 END) AS general_total_Course1
,SUM(CASE WHEN course_id = 3 
          THEN general_total ELSE 0 END) AS general_total_Course3
,SUM(CASE WHEN course_id = 1 
          THEN activity ELSE 0 END) AS Activity_Course1
,SUM(CASE WHEN course_id = 3 
          THEN activity ELSE 0 END) AS Activity_Course3
FROM grades
GROUP BY student_id, class_id

See this SQLFiddle

如果您不知道course_id的值,请使用此动态查询:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(case when `course_id` = ''',
      `course_id`,
      ''' then general_total END) AS `general_total_course_',
      `course_id`, '`'
    )
  ) INTO @sql
FROM grades;

SET @sql1 = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(case when `course_id` = ''',
      `course_id`,
      ''' then activity END) AS `activity_Course_',
      `course_id`, '`'
    )
  ) INTO @sql1
FROM grades;

SET @sql = CONCAT('SELECT student_id, class_id, ', @sql,',', @sql1, '
                  FROM grades 
                   GROUP BY student_id, class_id 
                  ');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

See this SQLFiddle

输出:

╔════════════╦══════════╦════════════════════════╦════════════════════════╦═══════════════════╦═══════════════════╗
║ STUDENT_ID ║ CLASS_ID ║ GENERAL_TOTAL_COURSE_1 ║ GENERAL_TOTAL_COURSE_3 ║ ACTIVITY_COURSE_1 ║ ACTIVITY_COURSE_3 ║
╠════════════╬══════════╬════════════════════════╬════════════════════════╬═══════════════════╬═══════════════════╣
║        330 ║       17 ║                     15 ║                     22 ║                55 ║                44 ║
║        331 ║       17 ║                     11 ║                     12 ║                13 ║                14 ║
╚════════════╩══════════╩════════════════════════╩════════════════════════╩═══════════════════╩═══════════════════╝

答案 1 :(得分:1)

如果存在未知值course_id,则首选动态SQL

-- COLUMN HEADER FOR general_total
SELECT  GROUP_CONCAT(DISTINCT
        CONCAT('MAX(CASE WHEN course_id = ''',
               course_id,
               ''' THEN general_total END) AS ',
               CONCAT('`general_total_course_', course_id, '`')
               )) INTO @general_total
FROM grades
WHERE  class_id = 17
ORDER BY course_id;

-- COLUMN HEADER FOR activity 
SELECT  GROUP_CONCAT(DISTINCT
        CONCAT('MAX(CASE WHEN course_id = ''',
               course_id,
               ''' THEN activity END) AS ',
               CONCAT('`general_total_activity_', course_id, '`')
               )) INTO @activity
FROM grades
WHERE  class_id = 17
ORDER BY course_id;

SET @sql = CONCAT('SELECT student_id, class_id, ', @general_total, ',
                          ', @activity, '
                   FROM   grades
                   WHERE  class_id = 17
                   GROUP  BY student_id, class_id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;