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

How to create mysql pivot table if row names are in separate table?

我有 3 个 table,我需要从中得到一个枢轴 table。

  1. Table - 问题
+------------+----------+
| id问题 |问题 |
+------------+----------+
| 1 |一季度 |
+------------+----------+
| 2 | Q2 |
+------------+----------+
  1. Table - question_answer
+------------+------------+--------+--------+
| idAnswer | id问题 |回答 |价值 |
+------------+------------+--------+--------+
| 1 | 1 | A1 | 100 |
+------------+------------+--------+--------+
| 2 | 1 | A2 | 101 |
+------------+------------+--------+--------+
| 3 | 2 | B1 | 200 |
+------------+------------+--------+--------+
  1. Table - 结果
+------------+------------+--------+--------+
| id 结果 | idAnswer |用户名 | .... |
+------------+------------+--------+--------+
| 1 | 1 | u1 | ... |
+------------+------------+--------+--------+
| 2 | 1 | u2 | ... |
+------------+------------+--------+--------+
| 3 | 3 | u3 | ... |
+------------+------------+--------+--------+

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

+---------+--------------+--------------+--------------+
| 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 |
+---------+--------------+--------------+--------------+

我阅读了很多问题,看到了很多解决方案,但没有一个符合我的问题。

问题中显示的结果集无法通过单个 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 列中重复相同的答案。

"trick" 是用于 return 每个 a.value 列的表达式,使用条件测试来查看 q 是否匹配特定的 question 我们想 return 在特定列中回答...

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())来找出答案 value 不是-NULL.

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 |

但问题是:不可能 动态更改 return 列的数量,或动态更改 return 列的数据类型或名称 return由来自 的 SQL 语句编辑,在 中 SQL 语句。

列数、数据类型和列名...这些都必须在 SELECT 语句提交到数据库时固定。

所以,最重要的是,结果集不能从你在 single SELECT 语句中的表中 returned,不可能使用表中的值作为列名,或改变语句中 returned 的列数。

但是,可以预先使用 separate SQL 语句从表中获取信息,因此我们可以动态构建我们需要的查询获取结果集。

注意:上面说明的 MAX(IF(,val,NULL)) ... GROUP BY ... 模式只是一种方法。很可能,您也遇到了 "correlated subquery in SELECT list" 模式的答案。同样的方法适用:运行 一个查询,获取构建查询所需的元数据,然后为第二个查询构建 SQL 文本(return 您真正想要的结果) .