嘿伙计们我有以下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个列),并且还有另一个表(模拟标志),因此性能非常重要。 我想知道这是否可能只用一个查询以及如何完全实现它?
答案 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?