[英]Group_Concat in Crosstab
With a table like: 用这样的表:
Name Event Time
Steve Start 19:53
Steve Event1 19:51
Steve Stop 19:45
Steve Start 18:13
Steve Event2 18:01
Steve Event1 17:51
Steve Stop 17:45
Bob Start 19:47
Bob Event2 19:31
Bob Stop 17:57
representing events that occur between start and stops times. 代表在开始时间和停止时间之间发生的事件。 I'd like to turn this into: 我想把它变成:
Name Start Stop Event1 Event2
Steve 19:53 19:45 1 0
Steve 18:13 17:45 1 1
Bob 19:47 17:57 0 1
My attempt: 我的尝试:
select
name,
(CASE event WHEN 'start' THEN time ELSE NULL END) AS Start,
(CASE event WHEN 'stop' THEN time ELSE NULL END) AS Stop,
(CASE event WHEN 'event1' THEN 1 ELSE 0 END) AS Event1,
(CASE event WHEN 'event2' THEN 1 ELSE 0 END) AS Event2
from atable
which results in: 结果是:
Name Start Stop Event1 Event2
Steve 19:53 0 0 0
Steve 0 0 1 0
Steve 0 19:45 0 0
Steve 18:13 0 0 0
Steve 0 0 0 1
Steve 0 0 1 0
Steve 0 17:45 0 0
Bob 19:47 0 0 0
Bob 0 0 1 0
Bob 0 17:57 0 0
How do I get the records in a single row? 如何单行获取记录?
I did try a Group_CONCAT per: 我确实尝试了一个Group_CONCAT:
select
name,
GROUP_CONCAT((CASE event WHEN 'start' THEN time ELSE 0 END)) AS Start,
GROUP_CONCAT((CASE event WHEN 'stop' THEN time ELSE 0 END)) AS Stop,
GROUP_CONCAT((CASE event WHEN 'event1' THEN 1 ELSE 0 END)) AS Event1,
GROUP_CONCAT((CASE event WHEN 'event2' THEN 1 ELSE 0 END)) AS Event2
from atable
group by name, event
But ended up with: 但最终导致:
Name Start Stop Event1 Event2
Bob 0 0 1 0
Bob 19:47 0 0 0
Bob 0 17:57 0 0
Steve 0,0 0,0 1,1 0,0
Steve 0 0 0 1
Steve 19:53,18:13 0,0 0,0 0,0
Steve 0,0 19:45,17:45 0,0 0,0
And now tested: Working SQL FIDDLE 并经过测试:有效的SQL FIDDLE
How do I get the records in a single row? 如何单行获取记录?
Max or min would combine the rows, but since name isn't unique enough we need a 2nd way to identify the group within the group which would result in a 2nd row in your output. 最大值或最小值将合并行,但是由于名称不够唯一,我们需要第二种方法来标识组中的组,这将在输出中导致第二行。 We can do this using user variables on the event start and a counter. 我们可以在事件开始和计数器上使用用户变量来执行此操作。
This assumes: 假设:
event
for the same user denote a new row needed in result. 同一用户在event
多次出现“开始”表示结果中需要新的一行。 . 。
***DDL***
CREATE table atable (
name varchar(10),
`event` varchar(10),
`time` time);
INSERT into atable values
('Steve', 'Start', '19:53'),
('Steve', 'Event1', '19:51'),
('Steve', 'Stop', '19:45'),
('Steve', 'Start', '18:13'),
('Steve', 'Event2', '18:01'),
('Steve', 'Event1', '17:51'),
('Steve', 'Stop', '17:45'),
('Bob', 'Start', '19:47'),
('Bob', 'Event2', '19:31'),
('Bob', 'Stop', '17:57');
***DML***
SELECT
name,
max(CASE event WHEN 'start' THEN time ELSE NULL END) AS Start,
max(CASE event WHEN 'stop' THEN time ELSE NULL END) AS Stop,
max(CASE event WHEN 'event1' THEN 1 ELSE 0 END) AS Event1,
max(CASE event WHEN 'event2' THEN 1 ELSE 0 END) AS Event2
FROM (SELECT A.*, CASE WHEN @Name=Name and Event = 'Start' THEN @GRP:=@GRP+1
WHEN @Name <> Name THEN @GRP:=@GRP+1
ELSE @GRP
end as mGROUP,
CASE WHEN @Name <> NAME then
@Name:=Name
END as Name2
FROM atable A
CROSS JOIN (Select @GRP:=0) x
CROSS JOIN (Select @Name:='') y
ORDER BY Name, Time Desc) z
GROUP BY Name, mGROUP
How this works: The inner query "Z" adds two columns, mGROUP and Name2 to your base data set "atable". 工作原理:内部查询“ Z”将两行mGROUP和Name2添加到基本数据集“ atable”中。 The Database engine initializes variables @GRP and @NAME via a cross join. 数据库引擎通过交叉联接初始化变量@GRP和@NAME。 We need @GRP so we can group each sub set of data together from atable to make it easier to combine the data. 我们需要@GRP,因此我们可以将每个子数据组从一起分组,以使合并数据更加容易。 This column represents the missing group by we need in order to use min/max to combine the rows in your pivot. 为了使用最小/最大组合您的数据透视图中的行,此列表示缺少的组。
The @Name variable is used as a control break method so we know when to increment the @grp counter. @Name变量用作控制中断方法,因此我们知道何时增加@grp计数器。 This value is reset in the Name2 column when the names vary. 名称不同时,将在“名称2”列中重置此值。 There are two times the @grp counter needs to be incremented. @grp计数器有两次需要增加。 Once is when a 'Start' event is encountered, once is when @Name changes. 一次是遇到“开始”事件,一次是@Name更改。 The mGROUP column does this increment for us and when no increment is needed, the same value is output as it's part of the same group. mGROUP列为我们执行此增量,并且在不需要增量时,将输出相同的值,因为它属于同一组。 (To see this work just run the inner query "Z" and evaluate the results) (要查看此工作,只需运行内部查询“ Z”并评估结果)
Now that we have the needed grouping mechanism to combine the groups using max, we can use simple aggregation to combine the rows which is done via the outer query. 现在,我们有了使用max组合组所需的分组机制,我们可以使用简单的聚合来组合通过外部查询完成的行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.