I'm looking for a (cleaner?) way to do the following:
Let's say I have a table, main, with ~15 columns that looks something like this, with one row per id:
main:
id start end col4 ... col15
666 2014-01-01 2014-06-30 ... ... ...
1234 2015-03-05 2015-05-02 ... ... ...
9876 2014-09-01 2015-01-01 ... ... ...
...(etc)
Then I have another table, events, which may have 0, 1, or many rows per id:
events:
id date code
666 2014-01-20 "code_a"
1234 2015-05-01 "code_b"
666 2014-01-25 "code_c"
666 2014-02-09 "code_z"
... (etc)
and finally I have a table, codes, which has one row per code, giving a description for the code as well as a type (0,1, or 2):
codes:
code desc type
"code_a" "something" 0
"code_b" "somethn else" 1
"code_c" "another thing" 0
"code_d" "one more" 2
(no code z)
and what I want as a result is main's 15 columns plus three additional columns which contain comma separated lists of event codes which happened between the start and end dates for that id by type (first column is type 0, second type 1, third type 2), so:
id start end ... col15 type_0 type_1 type_2
666 2014-01-01 2014-06-30 ... ... "code_a,code_c"
1234 2015-03-05 2015-05-02 ... ... "code_b"
...(etc)
my solution is
select m.*
, group_concat(c0) as type_0
, group_concat(c1) as type_1
, group_concat(c2) as type_2
from main m
left join events e on m.id = e.id and e.date between m.start and m.end
left join codes c0 on c0.code = e.code and c0.type = 0
left join codes c1 on c0.code = e.code and c0.type = 1
left join codes c2 on c0.code = e.code and c0.type = 2
group by m.id
, m.start
, m.end
, m.col4
, m.col5
, m.col6
, m.col7
, m.col8
, m.col9
, m.col10
, m.col11
, m.col12
, m.col13
, m.col14
, m.col15
But to me that's pretty nasty looking. Is there a more elegant way to do this (especially avoiding the 15 columns listed in the group by)?