Reputation: 225
Thanks in advance, I just can't seem to get it!
I have two tables
Category
Id Name 1 Aptitude 2 English
Mark
UserId CategoryId Mark 1 1 25 1 2 45 2 1 34 3 2 45 4 1 56 4 2 66
What I am looking to output is a mysql query is something to this effect
Output
UserId AptitudeMark EnglishMark 1 25 45 4 56 66
As I am new to mysql I could only get either one category or the other category and I can't get them in the same row as well. Also when the user is having both the category mark, we should consider.
Upvotes: 1
Views: 97
Reputation: 495
SELECT main.`id`,A.mark as AptitudeMark,E.mark as EnglishMark FROM `Mark` as main
LEFT JOIN (SELECT id,mark FROM `Mark` WHERE `CategoryId` = 1) as A ON main.id = A.id
LEFT JOIN (SELECT id,mark FROM `Mark` WHERE `CategoryId` = 2) as E ON main.id = E.id
GROUP BY main.id
Upvotes: 2
Reputation: 44864
If the categories are unknown then you will need to use dynamic sql for this and the query would look like
set @sql = null;
select
group_concat(distinct
concat(
'max(case when m.CategoryId = ''',
m.CategoryId,
''' then m.Mark end) AS ',
concat(c.Name,'Mark')
)
) into @sql
from Mark m join Category c on c.Id = m.CategoryId ;
set @sql = concat('select m.UserId, ', @sql, ' from Mark m
join Category c on c.Id = m.CategoryId
group by m.UserId
');
prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;
Here is a test case
mysql> select * from Category ;
+------+----------+
| Id | Name |
+------+----------+
| 1 | Aptitude |
| 2 | English |
+------+----------+
2 rows in set (0.00 sec)
mysql> select * from Mark ;
+--------+------------+------+
| UserId | CategoryId | Mark |
+--------+------------+------+
| 1 | 1 | 25 |
| 1 | 2 | 45 |
| 2 | 1 | 34 |
| 3 | 2 | 45 |
| 4 | 1 | 56 |
| 4 | 2 | 66 |
+--------+------------+------+
6 rows in set (0.00 sec)
Running above query will give
+--------+--------------+-------------+
| UserId | AptitudeMark | EnglishMark |
+--------+--------------+-------------+
| 1 | 25 | 45 |
| 2 | 34 | NULL |
| 3 | NULL | 45 |
| 4 | 56 | 66 |
+--------+--------------+-------------+
Upvotes: 1
Reputation: 11556
We can achieve this with the following query with CASE
expression and GROUP BY
clause, if the number of category
(s) is fixed.
Query
select * from
(
select UserId,
max(case when CategoryId = 1 then Mark else null end) as AptitudeMark,
max(case when CategoryId = 2 then Mark else null end) as EnglishMark
from Mark
group by UserId
)t
where t.AptitudeMark is not null
and t.EnglishMark is not null;
Upvotes: 1
Reputation: 2153
Try this query
SELECT UserId, GROUP_CONCAT(CategoryId,'-',Mark) AS Category_mark
FROM marks
GROUP BY UserId
Which will give you the result like
UserId Category_mark
1 1-25,2-45,
Upvotes: 0
Reputation: 167192
You can use a GROUP_CONCAT
, but the results will be somewhat different. Have a look at this:
SELECT `UserId`, GROUP_CONCAT(`CategoryId`), GROUP_CONCAT(`Mark`) FROM `marks`
GROUP BY `UserID`
Upvotes: 1