mysql将行转换为具有条件的列

时间:2015-06-17 10:48:42

标签: mysql

是否可以以这种方式将mysql行转换为列?

假设我有一个这样的表

+-----+--------------+---------+--------------+-------+
| id  | std_no       | exam_id | subject_code | score |
+-----+--------------+---------+--------------+-------+
|   1 | 1000         |       1 |          101 |    70 |
|   2 | 1000         |       1 |          102 |    75 |
|   3 | 1000         |       1 |          121 |    75 |
|   4 | 1000         |       1 |          231 |    69 |
|   7 | 1001         |       1 |          101 |    80 |
|   8 | 1001         |       1 |          102 |    70 |
|   9 | 1001         |       1 |          121 |    90 |
|  10 | 1001         |       1 |          231 |    80 |
| 127 | 1000         |       2 |          101 |    61 |
| 128 | 1000         |       2 |          102 |    85 |
| 129 | 1000         |       2 |          121 |    50 |
| 130 | 1000         |       2 |          231 |    54 |
| 133 | 1001         |       2 |          101 |    63 |
| 134 | 1001         |       2 |          102 |    14 |
| 135 | 1001         |       2 |          121 |    90 |
| 136 | 1001         |       2 |          231 |    25 |
+-----+--------------+---------+--------------+-------+

我需要根据以上内容创建一个新表:

+-----+----------------+-------------+-------+-------+
| id  | std_no         |subject_code | exam1 | exam2 |         
+-----+----------------+-------------+-------+-------+
| 1   | 1000           | 101         | 70    | 61    |
| 2   | 1000           | 102         | 75    | 85    |
| 3   | 1000           | 121         | 75    | 50    |
| 4   | 1000           | 231         | 69    | 54    |
| 5   | 1001           | 101         | 80    | 63    |
| 6   | 1001           | 102         | 70    | 14    |
| 7   | 1001           | 121         | 90    | 90    |
| 8   | 1001           | 231         | 80    | 25    |
+-----+----------------+-------------+-------+-------+

如通过第一个表格,获取 std_no subject_code 得分。但是我需要把scor 如果table1.exam_id = 1,则在exam1下的table2内,如果table1.exam_id = 2

,则在test2下的table2中

这可以用mysql吗?

4 个答案:

答案 0 :(得分:2)

对于动态exam_id,您需要创建一个动态查询来生成数据透视表,而不是

set @sql = null;
select
  group_concat(distinct
    concat(
      'max(case when exam_id = ''',
      exam_id,
      ''' then score end) AS ',
      concat('exam',exam_id)
    )
  ) into @sql
from exam;

set @sql = concat('select std_no,subject_code, ', @sql, ' from exam 
                  group by std_no,subject_code
                  order by std_no,subject_code
');

prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;

在预期的结果集中,您还有一些id增量顺序,为此,您可以更改上述查询以使用与

相同的用户定义变量
set @sql = null;
select
  group_concat(distinct
    concat(
      'max(case when exam_id = ''',
      exam_id,
      ''' then score end) AS ',
      concat('exam',exam_id)
    )
  ) into @sql
from exam;

set @sql = concat('select @rn:=@rn+1 as id,std_no,subject_code, ', @sql, ' from exam,(select @rn:=0)x
                  group by std_no,subject_code
                  order by std_no,subject_code
');

prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;

<强> DEMO

答案 1 :(得分:0)

这些查询为您提供与输出值有些类似的记录

SELECT id,std_no,subject_code,
  (CASE exam_id WHEN 1 THEN score ELSE NULL END) as exam1,
  (CASE exam_id WHEN 2 THEN score ELSE NULL END) as exam2
FROM table;

答案 2 :(得分:0)

您可以使用自我加入

执行此操作
SELECT a.id,a.std_no,a.subject_code,
  a.score as exam1,b.score as exam2
FROM table a join table b
  on a.std_no=b.std_no and 
  a.subject_code=b.subject_code 
  WHERE a.exam_id=1 and b.exam_id=2;

答案 3 :(得分:0)

只需使用条件聚合:

SELECT MIN(id) as id, std_no, subject_code,
       MAX(CASE WHEN exam_id = 1 THEN score END) as exam1,
       MAX(CASE WHEN exam_id = 2 THEN score END) as exam2
FROM table
GROUP BY std_no, subject_code;