1

Hey guys I have the following 3 tables:

      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     |

So "person" and "attendance" are growing dynamically and "event" is a static table to hold the event names. I am trying to achieve the following result:

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

I should propably mention that my live database is quite big (I have like 11 static event names, so this example would end up with 14 columns) and there is also another table (simulating flags) in between so performance is quite important. I wonder if this is even possible with one single query and how to exactly achieve it?

4

1 回答 1

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;

You need the list of event names before you can write this query.


Re your comment, I see what you mean, there are no rows for ryan attending any event, so that person doesn't show up in the result. The JOIN only returns person rows that have one or more matching attendance rows.

The way to solve this is with a LEFT OUTER JOIN. That returns the person row whether there are matching rows or not.

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: Shouldn't the id column in your sample result have values 5 and 6?

于 2013-07-10T20:22:13.347 回答