Concordo com as outras respostas, que
GROUP_CONCAT
junto com o PHP para dividir os valores separados por vírgulas é provavelmente a melhor abordagem, no entanto, se por qualquer outro motivo você precisar da saída sugerida via Pure SQL, sugiro uma das seguintes abordagens. 1. Auto-junções
SELECT t1.Name,
MIN(t1.Subject) AS Sub1,
MIN(t2.Subject) AS Sub2,
MIN(t3.Subject) AS Sub3,
MIN(t4.Subject) AS Sub4
FROM Students t1
LEFT JOIN Students T2
ON t1.Name = t2.Name
AND t2.Subject > t1.Subject
LEFT JOIN Students T3
ON t2.Name = t3.Name
AND t3.Subject > t2.Subject
LEFT JOIN Students T4
ON t3.Name = t4.Name
AND t4.Subject > t3.Subject
GROUP BY t1.Name;
2. Usando uma função de tipo ROW_NUMBER para agregar
SELECT Name,
MAX(IF(RowNum = 1,Subject, NULL)) AS Sub1,
MAX(IF(RowNum = 2,Subject, NULL)) AS Sub2,
MAX(IF(RowNum = 3,Subject, NULL)) AS Sub3,
MAX(IF(RowNum = 4,Subject, NULL)) AS Sub4
FROM ( SELECT Name,
Subject,
@r:= IF(@Name = Name, @r + 1, 1) AS RowNum,
@Name:= Name AS Name2
FROM Students,
(SELECT @Name:='') n,
(SELECT @r:= 0) r
ORDER BY Name, Sno
) t
GROUP BY Name