简体   繁体   English

MySQL中的数据透视表 - 使用varchar格式的值转换为数据透视表

[英]Pivot table in MySQL - convert to pivot table with values in varchar format

i would like convert data from Table1 as you can see on first picture on data in Pivot_table. 我希望转换Table1中的数据,如Pivot_table中数据的第一张图片所示。 Is possible to do that in MySQL? 有可能在MySQL中这样做吗? Because the values of pivot table(A, B, C, D) are in varchar data format and i cannot use any aggregation function of MySQL like SUM or others. 因为数据透视表(A,B,C,D)的值是varchar数据格式,我不能像SUM那样使用MySQL的任何聚合函数。

Table1:
PK        Name     Subject     Grade
-------------------------------------
1         Bob       Math        A
2         Bob       History     B
3         Bob       Language    C
4         Bob       Biology     D
5         Sue       History     C
6         Sue       Math        A
7         Sue       Music       A
8         Sue       Geography   C


Pivot_table:
Subject     Bob     Sue
-------------------------
Math        A        A
History     B        C
Language    C 
Biology     D
Music                A
Geography            C

Thanks for your help 谢谢你的帮助

A static query (as far as only Bob and Sue are concerned) might look like this 静态查询(仅涉及Bob和Sue)可能如下所示

SELECT subject, 
       MAX(CASE WHEN name = 'Bob' THEN grade END) `Bob`,
       MAX(CASE WHEN name = 'Sue' THEN grade END) `Sue` 
  FROM table1 
 GROUP BY subject

Now to be able to account for other names use dynamic SQL like this 现在能够考虑其他名称使用像这样的动态SQL

SET @sql = NULL;

SELECT GROUP_CONCAT(DISTINCT
         CONCAT('MAX(CASE WHEN name = ''', name,
                ''' THEN grade END) `', name, '`'))
  INTO @sql
  FROM table1;

SET @sql = CONCAT('SELECT subject, ', @sql, ' 
                     FROM table1 
                    GROUP BY subject');

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

Output: 输出:

|   SUBJECT |    BOB |    SUE |
|-----------|--------|--------|
|   Biology |      D | (null) |
| Geography | (null) |      C |
|   History |      B |      C |
|  Language |      C | (null) |
|      Math |      A |      A |
|     Music | (null) |      A |

Here is SQLFiddle demo 这是SQLFiddle演示


You can wrap it into a stored procedure to simplify things on the calling end 您可以将其包装到存储过程中以简化调用端的操作

DELIMITER $$
CREATE PROCEDURE sp_grade_report()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(DISTINCT
           CONCAT('MAX(CASE WHEN name = ''', name,
                  ''' THEN grade END) `', name, '`'))
    INTO @sql
    FROM table1;

  SET @sql = CONCAT('SELECT subject, ', @sql, ' 
                       FROM table1 
                      GROUP BY subject');

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;

Sample usage: 样品用法:

CALL sp_grade_report();

Here is SQLFiddle demo 这是SQLFiddle演示

Write a stored procedure for the convertion. 为转换编写存储过程。

  1. SELECT DISTINCT name FROM table1; to get list of columns for the Pivot_table. 获取Pivot_table的列列表。 Create the table with appropriate number of columns + 1 for Subject. 为主题创建具有适当列数+ 1的表。

  2. Insert all the subjects in the pivot table to get 1 row for each subject. 在数据透视表中插入所有主题,为每个主题获得1行。 INSERT ... from SELECT DISTINCT subject FROM table1 . INSERT ... from SELECT DISTINCT subject FROM table1

  3. Create cursor to retrieve all the records from the table1. 创建游标以从table1中检索所有记录。 Go through all the rows of the cursor and for each row call UPDATE Pivot_table SET [COLUMN_NAME for studetn value]=[grade value] WHERE subject=[subject name value]; 遍历游标的所有行,并为每一行调用UPDATE Pivot_table SET [COLUMN_NAME for studetn value]=[grade value] WHERE subject=[subject name value];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM