子选择动态行数作为单个查询中的列

时间:2013-07-10 20:03:58

标签: mysql pivot-table

嘿伙计们我有以下3个表:

      person                    event                       attendance
| id | name | age | | id |   name  |    added   | | id | pId | eId | attended |
|-----------------| |---------------------------| |---------------------------|
| 5  | bob  | 20  | | 0  | wedding | 01.01.2013 | | 0  |  5  |  0  |   YES    |
| 6  | ryan | 25  | | 1  |  party  | 01.01.2013 | | 1  |  5  |  1  |   NO     |

所以“人”和“出勤”正在动态增长,“事件”是一个静态表来保存事件名称。我想要达到以下结果:

| id | name | age | wedding | party |
|-----------------------------------|
| 0  | bob  | 20  |   YES   |  NO   |
| 1  | ryan | 25  |   NO    |  NO   |

我应该提到我的实时数据库非常大(我有11个静态事件名称,因此这个例子最终会有14个列),并且还有另一个表(模拟标志),因此性能非常重要。 我想知道这是否可能只用一个查询以及如何完全实现它?

1 个答案:

答案 0 :(得分:2)

SELECT p.id, p.name, p.age, 
  MAX(IF(e.name='wedding', a.attended, NULL)) AS `wedding`,
  MAX(IF(e.name='party', a.attended, NULL)) AS `party`
FROM person p
JOIN attendance a ON a.pId = p.id
JOIN event e ON a.eId = e.id
GROUP BY p.id;

在编写此查询之前,您需要事件名称列表。


重新评论,我明白你的意思,ryan参加任何活动都有没有行,因此该人不会出现在结果中。 JOIN仅返回具有一个或多个匹配出勤行的人员行。

解决此问题的方法是使用LEFT OUTER JOIN。这将返回person行是否有匹配的行。

SELECT p.id, p.name, p.age,
  COALESCE(MAX(IF(e.name='wedding', a.attended, NULL)), 'NO')AS `wedding`,
  COALESCE(MAX(IF(e.name='party', a.attended, NULL)), 'NO') AS `party`
FROM person p
LEFT OUTER JOIN attendance a ON a.pId = p.id
LEFT OUTER JOIN event e ON a.eId = e.id
GROUP BY p.id;

+----+------+------+---------+-------+
| id | name | age  | wedding | party |
+----+------+------+---------+-------+
|  5 | bob  |   20 | YES     | NO    |
|  6 | ryan |   25 | NO      | NO    |
+----+------+------+---------+-------+

PS:样本结果中的id列是否应该具有值5和6?