A static query (as far as only Bob and Sue are concerned) might look like this
SELECT subject,
MAX(CASE WHEN name = 'Bob' THEN grade END) `Bob`,
MAX(CASE WHEN name = 'Sue' THEN grade END) `Sue`
FROM table1
GROUP BY subject
Now to be able to account for other names use dynamic SQL like this
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('MAX(CASE WHEN name = ''', name,
''' THEN grade END) `', name, '`'))
INTO @sql
FROM table1;
SET @sql = CONCAT('SELECT subject, ', @sql, '
FROM table1
GROUP BY subject');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Output:
| SUBJECT | BOB | SUE |
|-----------|--------|--------|
| Biology | D | (null) |
| Geography | (null) | C |
| History | B | C |
| Language | C | (null) |
| Math | A | A |
| Music | (null) | A |
Here is SQLFiddle demo
You can wrap it into a stored procedure to simplify things on the calling end
DELIMITER $$
CREATE PROCEDURE sp_grade_report()
BEGIN
SET @sql = NULL;
SELECT GROUP_CONCAT(DISTINCT
CONCAT('MAX(CASE WHEN name = ''', name,
''' THEN grade END) `', name, '`'))
INTO @sql
FROM table1;
SET @sql = CONCAT('SELECT subject, ', @sql, '
FROM table1
GROUP BY subject');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Sample usage:
CALL sp_grade_report();
Here is SQLFiddle demo
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…