我在MySQL中有一个名为map_item_group的表,如下例所示:
item_serial | group_code | start_date | end_date
===================================================
item1 | group1 | 2015-01-01 | 2016-01-01
item1 | group2 | 2016-02-01 | 2016-03-15
item2 | group1 | 2015-06-01 | 2016-06-30
item1 | group2 | 2016-05-18 | 2016-06-30
我想创建一个名为group_info的MySQL视图,如下所示:
group_code | start_date | end_date | items_string
=======================================================
group1 | 2015-01-01 | 2015-06-01 | item1
group1 | 2015-06-01 | 2016-01-01 | item1,item2
group1 | 2016-01-01 | 2016-06-30 | item2
group2 | 2016-02-01 | 2016-03-15 | item1
group2 | 2016-05-18 | 2016-06-30 | item1
换句话说,我想为每个组显示一行,在每个时间跨度显示该组中的项目。
只需按group_code,start_date和end_date(即SELECT group_code, start_date, end_date, GROUP_CONCAT(item_serial) FROM map_item_group GROUP BY group_code, start_date, end_date
)进行分组,就无法提供所需的输出。
我可以想象用子查询做到这一点的方法,但MySQL视图中不允许使用子查询。我可以创建其他视图来代替子查询作为一种解决方法,但我宁愿避免在我的模式中添加一堆额外的视图。最干净的方法是什么?
答案 0 :(得分:0)
(start + end)
group_code
创建所有日期UNION
的列表我调用T1
,但应选择其他名称T1
和T2
R
<强> OUPUT 强>
<强> SQL Demo 强>
SELECT R.`group_code`, R.`start_date`, R.`end_date`, GROUP_CONCAT(T.item_serial SEPARATOR ', ') items
FROM (
SELECT T1.`group_code`, T1.range_date as start_date, T2.range_date as end_date
FROM (
SELECT `group_code`, range_date,
@rn := IF( @grpCode = `group_code`, @rn + 1 , IF(@grpCode := `group_code`, 1, 1)) as rn
FROM (
SELECT `group_code`, `start_date` as range_date
FROM Table1
UNION
SELECT `group_code`, `end_date` as range_date
FROM Table1
ORDER BY 1, 2
) as T1,
(SELECT @rn := 0, @grpCode := '') r
) T1
JOIN (
SELECT `group_code`, range_date,
@rn := IF( @grpCode = `group_code`, @rn + 1 , IF(@grpCode := `group_code`, 1, 1)) as rn
FROM (
SELECT `group_code`, `start_date` as range_date
FROM Table1
UNION
SELECT `group_code`, `end_date` as range_date
FROM Table1
ORDER BY 1, 2
) as T1,
(SELECT @rn := 0, @grpCode := '') r
) T2
ON T1.rn = T2.rn -1
AND T1.group_code = T2.group_code
) R
JOIN Table1 T
ON R.start_date < T.end_date
AND R.end_date > T.start_date
AND R.group_code = T.group_code
GROUP BY R.`group_code`, R.`start_date`, R.`end_date`
ORDER BY 1,2, 4