【问题标题】:turning table rows into columns in mysql将表行转换为mysql中的列
【发布时间】:2013-05-18 00:12:58
【问题描述】:

假设我有一个类似于以下的数据库:

表 student_info:

id    name
111   jon
112   dan
113   david
...

和表格分数:

item_id    student_id    score
01         111           37
02         111           45
01         112           55
02         112           44
01         113           66
02         113           45
...

是否可以做一个mysql查询来生成下表?:

Student_Name  ITEM_1_SCORE  ITEM_2_SCORE
jon           37            45
dan           55            44
david         66            45
...

如果是这样,语法是什么?不知道这是join操作还是别的什么?

谢谢。

【问题讨论】:

  • 是的,这是可能的。这是一个简单的数据透视表查询 - 但通常最好在应用程序级别处理这类事情(数据显示问题)。

标签: mysql join syntax pivot-table


【解决方案1】:

如果item_id 只有两个值,则可以硬编码值。示例

SELECT  a.Name AS Student_Name,
        MAX(CASE WHEN item_id = '01' THEN b.score END) Item_1_Score,
        MAX(CASE WHEN item_id = '02' THEN b.score END) Item_2_Score
FROM    student_info a
        LEFT JOIN scores b
            ON a.id = b.student_ID
GROUP   BY a.Name

否则,当您不知道分数时,更喜欢Dynamic SQL

SELECT  GROUP_CONCAT(DISTINCT
        CONCAT('MAX(CASE WHEN item_id = ''',
               item_id,
               ''' THEN Score END) AS ',
               CONCAT('`Item_', item_id, '_Score`')
               )) INTO @sql
FROM scores;

SET @sql = CONCAT('SELECT   a.Name AS Student_Name, ', @sql, ' 
                    FROM    student_info a
                            LEFT JOIN scores b
                                ON a.id = b.student_ID
                    GROUP   BY a.Name');

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

两个查询的输出相同

╔══════════════╦══════════════╦══════════════╗
║ STUDENT_NAME ║ ITEM_1_SCORE ║ ITEM_2_SCORE ║
╠══════════════╬══════════════╬══════════════╣
║ dan          ║           55 ║           44 ║
║ david        ║           66 ║           45 ║
║ jon          ║           37 ║           45 ║
╚══════════════╩══════════════╩══════════════╝

【讨论】:

  • 这实际上帮助了我更多,因为我有大约 45 件物品!我想我一开始是被我不懂的语法吓到了。
【解决方案2】:

像这样:

SELECT
  i.name AS Student_Name,
  MAX(CASE WHEN s.item_id = 1 THEN score END) AS ITEM_1_SCORE, 
  MAX(CASE WHEN s.item_id = 2 THEN score END) AS ITEM_2_SCORE
FROM student_info AS i
INNER JOIN scores AS s ON s.student_id = i.id
GROUP BY i.name;

在这里查看它的实际效果:

这会给你:

| STUDENT_NAME | ITEM_1_SCORE | ITEM_2_SCORE |
----------------------------------------------
|          dan |           55 |           44 |
|        david |           66 |           45 |
|          jon |           37 |           45 |

【讨论】:

    猜你喜欢
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    • 2012-12-06
    相关资源
    最近更新 更多