如果行名在单独的表中,如何创建mysql数据透视表?

时间:2015-02-03 23:56:11

标签: mysql select pivot multiple-tables

我有3张桌子,我需要从中获取一个数据透视表。

  1. 表格 - 问题
  2. +------------+----------+  
    | idQuestion | question |  
    +------------+----------+  
    | 1          | Q1       |  
    +------------+----------+  
    | 2          | Q2       |  
    +------------+----------+
    
    1. 表格 - question_answer
    2. +------------+------------+----------+-------+  
      | idAnswer   | idQuestion | answer   | value |  
      +------------+------------+----------+-------+  
      | 1          | 1          | A1       | 100   |  
      +------------+------------+----------+-------+  
      | 2          | 1          | A2       | 101   |  
      +------------+------------+----------+-------+  
      | 3          | 2          | B1       | 200   |  
      +------------+------------+----------+-------+  
      
      1. 表格 - 结果
      2. +------------+------------+----------+-------+  
        | idResult   | idAnswer   | idUser   | ....  |  
        +------------+------------+----------+-------+  
        | 1          | 1          | u1       | ...   |  
        +------------+------------+----------+-------+  
        | 2          | 1          | u2       | ...   |  
        +------------+------------+----------+-------+  
        | 3          | 3          | u3       | ...   |  
        +------------+------------+----------+-------+  
        

        我需要从结果中获取数据透视表。我需要它喜欢这样的东西:

        +---------+--------------+--------------+--------------+
        | idUser  | Q1           | Q2           | Qn           |
        +---------+--------------+--------------+--------------+
        | u1      | answer.value | answer.value | answer.value |
        +---------+--------------+--------------+--------------+
        | u2      | answer.value | answer.value | answer.value |
        +---------+--------------+--------------+--------------+
        | u2      | answer.value | answer.value | answer.value |
        +---------+--------------+--------------+--------------+
        

        我已经阅读了很多问题,看到了许多决议,但没有任何问题符合我的问题。

1 个答案:

答案 0 :(得分:0)

如问题所示,结果集无法使用单个SELECT语句获得。

获得此类结果的一种方法是考虑获得这样的结果:

+---------+----+-------------+-------------+-------------+
| idUser  | q  | a.value     | a.value     | a.value     |
+---------+----+-------------+-------------+-------------+
| u1      | Q1 | a.value=101 | a.value=101 | a.value=101 |
| u1      | Q2 | a.value=200 | a.value=200 | a.value=200 |
| u1      | Qn | a.value=NNN | a.value=NNN | a.value=NNN |

即每个用户和问题的一行,以及答案。考虑在每个Ans.x列中重复的SAME答案。

“技巧”是用于返回每个a.value列的表达式,使用条件测试来查看q是否与我们想要返回的特定question相匹配特定栏目......

SELECT r.idUser
     , q.q
     , IF(q.q='Q1',a.value,NULL) AS AnsQ1
     , IF(q.q='Q2',a.value,NULL) AS AnsQ2
     , IF(q.q='Qn',a.value,NULL) AS AnsQn
     , ...
  FROM ...

所以我们会得到这样的结果:

+---------+----+-------------+-------------+-------------+
| idUser  | q  | AnsQ1       | AnsQ2       | AnsQn       |
+---------+----+-------------+-------------+-------------+
| u1      | Q1 | a.value=101 | NULL        | NULL        |
| u1      | Q2 | NULL        | a.value=200 | NULL        |
| u1      | Qn | NULL        | NULL        | a.value=NNN |

使用该结果,我们可以添加GROUP BY idUser,并使用聚合函数(MIN()MAX())来选择非NULL的答案value

SELECT r.idUser
     , MAX(IF(t.q='Q1',a.value,NULL)) AS AnsQ1
     , MAX(IF(t.q='Q2',a.value,NULL)) AS AnsQ2
     , MAX(IF(t.q='Qn',a.value,NULL)) AS AnsQn
     , ... 
  FROM ...
 GROUP BY r.idUser

获得这样的结果:

+---------+-------------+-------------+-------------+
| idUser  | AnsQ1       | AnsQ2       | AnsQn       |
+---------+-------------+-------------+-------------+
| u1      | a.value=101 | a.value=200 | a.value=NNN |

但问题是:不可能动态更改返回的列数,或动态更改SQL语句从返回的列的数据类型或名称/ em> SQL语句。

列的数量,数据类型和列的名称......在将SELECT语句提交到数据库时,这些都必须是FIXED。

因此,在底线,结果集不能从 SELECT语句中的表中返回,不能使用表中的值作为列名,或者改变列数从声明中返回。

然而,事先可以使用单独的 SQL语句来从表中获取信息,因此我们可以动态构建获取结果集所需的查询。

注意:上面说明的MAX(IF(,val,NULL)) ... GROUP BY ...模式只是一种方法。可能,您也遇到了“SELECT列表中的相关子查询”模式的答案。同样的方法适用:运行查询,获取构建查询所需的元数据,然后为第二个查询构建SQL文本(返回实际需要的结果)。