MySQL 数据透视表列数据作为行

Posted

技术标签:

【中文标题】MySQL 数据透视表列数据作为行【英文标题】:MySQL Pivot Table Column Data as Rows 【发布时间】:2013-03-27 10:11:04 【问题描述】:

我正在努力寻找解决这个 mysql 问题的方法。我似乎无法理解如何做到这一点。我有以下表格。

Question table
+----+-------------+
| id | question    |
+----+-------------+
| 1  | Is it this? |
| 2  | Or this?    |
| 3  | Or that?    |
+----+-------------+

Results Table
+----+---------+--------+
| id | user_id | job_id |
+----+---------+--------+
| 1  | 1       | 1      |
| 2  | 1       | 3      |
| 3  | 2       | 3      |
+----+---------+--------+

Answers table
+----+-------------------------+--------------+
| id | answer | fk_question_id | fk_result_id |
+----+-------------------------+--------------+
| 1  | Yes    | 1              | 1            |
| 2  | No     | 2              | 1            |
| 3  | Maybe  | 3              | 1            |
| 4  | Maybe  | 1              | 2            |
| 5  | No     | 2              | 2            |
| 6  | Maybe  | 3              | 2            |
| 7  | Yes    | 1              | 3            |
| 8  | Yes    | 2              | 3            |
| 9  | No     | 3              | 3            |
+----+-------------------------+--------------+

如果可能,我想将问题答案显示为每个结果集的列,如下所示。

+-----------+---------+--------+-------------+----------+----------+
| result_id | user_id | job_id | Is it this? | Or this? | Or that? |
+-----------+---------+--------+-------------+----------+----------+
| 1         | 1       | 1      | Yes         | No       | Maybe    |
| 2         | 1       | 3      | Maybe       | No       | Maybe    |
| 3         | 2       | 3      | Yes         | Yes      | No       |
+-----------+---------+--------+-------------+----------+----------+

任何帮助将不胜感激。

谢谢

【问题讨论】:

【参考方案1】:
SELECT  a.ID,
        a.user_ID,
        a.job_id,
        MAX(CASE WHEN c.question = 'Is it this?' THEN b.answer END) 'Is it this?',
        MAX(CASE WHEN c.question = 'Or this?' THEN b.answer END) 'Or this?',
        MAX(CASE WHEN c.question = 'Or that? ' THEN b.answer END) 'Or that? '
FROM    Results a
        INNER JOIN Answers b
            ON a.id = b.fk_result_id
        INNER JOIN Question c
            ON b.fk_question_id = c.ID
GROUP   BY a.ID,
        a.user_ID,
        a.job_id
SQLFiddle Demo

如果您的问题数量未知(像 Matei Mihai 所说的那样特别是 1000 个),则非常需要动态版本。

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN c.question = ''',
      question,
      ''' then b.answer end) AS ',
      CONCAT('`',question,'`')
    )
  ) INTO @sql
FROM Question;

SET @sql = CONCAT('SELECT  a.ID,
                            a.user_ID,
                            a.job_id, ', @sql, ' 
                    FROM    Results a
                            INNER JOIN Answers b
                                ON a.id = b.fk_result_id
                            INNER JOIN Question c
                                ON b.fk_question_id = c.ID
                    GROUP   BY a.ID,
                            a.user_ID,
                            a.job_id');

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

输出

╔════╦═════════╦════════╦═════════════╦══════════╦══════════╗
║ ID ║ USER_ID ║ JOB_ID ║ IS IT THIS? ║ OR THIS? ║ OR THAT? ║
╠════╬═════════╬════════╬═════════════╬══════════╬══════════╣
║  1 ║       1 ║      1 ║ Yes         ║ No       ║ Maybe    ║
║  2 ║       1 ║      3 ║ Maybe       ║ No       ║ Maybe    ║
║  3 ║       2 ║      3 ║ Yes         ║ Yes      ║ No       ║
╚════╩═════════╩════════╩═════════════╩══════════╩══════════╝

【讨论】:

如果有 1000 个问题怎么办? :) 很好的答案.. :) 我很确定他的表格中可能有 3 个以上的问题.. 这就是我要求动态查询的原因。来自我的 +1 是的,有超过 3 个问题,但对于这种情况,永远不会超过 20 个左右的问题。这是一个很好的解决方案。感谢您这么快的回复。

以上是关于MySQL 数据透视表列数据作为行的主要内容,如果未能解决你的问题,请参考以下文章

过滤数据透视表列,仅在

数据透视表列重命名

PowerQuery处理透视表总计行不能自定义计算

如何使用codeigniter显示mysql数据透视表数据

SQL 动态数据透视表列顺序

是否可以像在 Excel 中一样合并数据透视表列 OBIEE 12c 的单元格和中心?