我正在寻找一种(更清洁的?)方法来执行以下操作:
假设我有一个表,主表,有大约 15 列,看起来像这样,每个 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.code) as type_0
, group_concat(c1.code) as type_1
, group_concat(c2.code) 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 c1.code = e.code and c1.type = 1
left join codes c2 on c2.code = e.code and c2.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
但对我来说,这看起来很讨厌。有没有更优雅的方式来做到这一点(特别是避免 group by 中列出的 15 列)?
最佳答案
在 MySQL 中,您可以只使用 GROUP BY m.id
。除非您启用 ONLY_FULL_GROUP_BY
选项,否则它允许您使用不在 GROUP BY
子句中的非聚合列。如果您选择的列不是由分组列唯一标识的列,这可能会产生不可预测的结果,但这里不是这种情况——您正在按 m
表的唯一 ID 的列进行分组,并且所有非聚合列都来自同一个表。
在严格的 SQL 中,您必须通过在子查询中执行 GROUP_CONCAT
来完成此操作,然后将其与 main
表连接。
SELECT *
FROM (SELECT m.id,
, group_concat(c0.code) as type_0
, group_concat(c1.code) as type_1
, group_concat(c2.code) 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 c1.code = e.code and c1.type = 1
left join codes c2 on c2.code = e.code and c2.type = 2
GROUP BY m.id
) t1
JOIN main m ON t1.id = m.id
关于MySQL 按除一列以外的所有列分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31125192/