While fthiella's approach is the most common way to build a pivot table, you may want to try this query, which is faster in most cases:
SELECT
years.year,
COALESCE(tim.c, 0) AS tim,
COALESCE(pol.c, 0) AS pol,
COALESCE(pol.c, 0) AS ron
FROM (SELECT year FROM yourtable GROUP BY year) AS years
LEFT JOIN (
SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'tim' GROUP BY year
) AS tim ON (tim.year = years.year)
LEFT JOIN (
SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'pol' GROUP BY year
) AS pol ON (pol.year = years.year)
LEFT JOIN (
SELECT COUNT(name) AS c, year FROM yourtable WHERE name = 'ron' GROUP BY year
) AS ron ON (ron.year = years.year)
GROUP BY years.year;
This is a bit more painful to write, and to perform well, it requires two indexes:
- a two-columns index on both fields used as column and row discriminant, in this order (ie. in your case, on
(name, year) in this order)
- an index on the row discriminant (ie. in your case, on
(year))
But the larger the result (either more rows or more columns or both), the faster it performs compared to the usual approach. I posted some sample data here if anyone feels like playing with it. The corresponding queries are here.