如何解决根据顺序行模式的匹配将SQL行折叠为一行
我正在从事一个项目,该项目涉及将一系列动作组合为序列。特定的编程问题是,我想弄清楚当这些行与特定序列匹配时如何使用sql(最好是MysqL)组合表中的多行。需要注意的是,该表按其他两列分组(谁做的以及他们在哪一天做的)。
在此示例中,我们正在处理人们早间活动的动作列表。我们要将动作列表分为两个动作序列:唤醒/延后的警报和开始日期。唤醒/延后的警报序列是(唤醒行)->(延后警报)行。一天的开始顺序是(唤醒行)->(吃早餐行)->(刷牙行)。
我们的原始操作表如下:
我们所需的输出如下所示:
到目前为止,我已经研究了使用MysqL的窗口函数和迭代,但是这两者似乎都无法扩展到我要匹配多个序列这一事实。
我觉得这在sql中可能是不可能的,但是我认为我会在这里发布它,以防其他人知道如何解决该数据处理问题。最终目标是将这些结果存储在视图中,以便以后我们每次查询动作表时,都将查询“已处理”动作(即,将动作分组为序列后的动作)。
解决方法
如果我理解正确,则可以使用lead()
,然后再使用一些过滤逻辑。首先,分配新操作:
select t.*,(case when (actionid,next_actionid) = ('wokeUp','snoozedAlarm')
then 'wokeup and snoozed'
when (actionid,next_actionid,next2_actionid) = ('wokeUp','ateBreakfast','brushedTeeth')
then 'started day'
else actionid
end) as action,from (select t.*,lead(actionId,1) over (partition by person,day order by id) as next_actionid,2) over (partition by person,day order by id) as next2_actionid
from t
) t;
接下来,使用以下信息进行过滤:
with newactions as (
select t.*,'snoozedAlarm')
then 'wokeup and snoozed'
when (actionid,'brushedTeeth')
then 'started day'
else actionid
end) as action,'snoozedAlarm')
then 2
when (actionid,'brushedTeeth')
then 1
else 0
end) as duration
from (select t.*,day order by id) as next2_actionid
from t
) t
)
select na.*
from (select na.*,lag(duration) over (partition by person order by id) as prev_duration,lag(duration) over (partition by person order by id) as prev2_duration
from newactions na
) na
where not (prev_duration >= 1 or
prev2_duration >= 2
)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。