Reputation: 449
Say I have a database similar to the following:
Table student_info:
id name
111 jon
112 dan
113 david
...
and table scores:
item_id student_id score
01 111 37
02 111 45
01 112 55
02 112 44
01 113 66
02 113 45
...
Is it possible to do a mysql query to generate the following table?:
Student_Name ITEM_1_SCORE ITEM_2_SCORE
jon 37 45
dan 55 44
david 66 45
...
If so, what would the syntax be? I don't know if this is a join operation or something else?
thanks.
Upvotes: 1
Views: 3089
Reputation: 263833
If you have only two values for item_id
, then it is fine to hard code values. Example
SELECT a.Name AS Student_Name,
MAX(CASE WHEN item_id = '01' THEN b.score END) Item_1_Score,
MAX(CASE WHEN item_id = '02' THEN b.score END) Item_2_Score
FROM student_info a
LEFT JOIN scores b
ON a.id = b.student_ID
GROUP BY a.Name
Otherwise, when you have unknow number of scores, a Dynamic SQL
is much prefered.
SELECT GROUP_CONCAT(DISTINCT
CONCAT('MAX(CASE WHEN item_id = ''',
item_id,
''' THEN Score END) AS ',
CONCAT('`Item_', item_id, '_Score`')
)) INTO @sql
FROM scores;
SET @sql = CONCAT('SELECT a.Name AS Student_Name, ', @sql, '
FROM student_info a
LEFT JOIN scores b
ON a.id = b.student_ID
GROUP BY a.Name');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Both queries will OUTPUT the same
╔══════════════╦══════════════╦══════════════╗
║ STUDENT_NAME ║ ITEM_1_SCORE ║ ITEM_2_SCORE ║
╠══════════════╬══════════════╬══════════════╣
║ dan ║ 55 ║ 44 ║
║ david ║ 66 ║ 45 ║
║ jon ║ 37 ║ 45 ║
╚══════════════╩══════════════╩══════════════╝
Upvotes: 7
Reputation: 79969
Like this:
SELECT
i.name AS Student_Name,
MAX(CASE WHEN s.item_id = 1 THEN score END) AS ITEM_1_SCORE,
MAX(CASE WHEN s.item_id = 2 THEN score END) AS ITEM_2_SCORE
FROM student_info AS i
INNER JOIN scores AS s ON s.student_id = i.id
GROUP BY i.name;
See it in action here:
This will give you:
| STUDENT_NAME | ITEM_1_SCORE | ITEM_2_SCORE |
----------------------------------------------
| dan | 55 | 44 |
| david | 66 | 45 |
| jon | 37 | 45 |
Upvotes: 4