如果在下面的示例表中有两个跟随和连接事件的值为110并且所有具有相同id
的事件时,如何选择具有值105的事件category
?
通过连接值为110的事件,我的意思是在110个具有相同类别的事件之间没有其他事件(如106或112)。
id category event
8 100 110
12 100 105
19 101 112
22 100 106
31 100 110
42 101 106
121 100 110
254 100 104
在上面的示例中,id 12将被返回,因为它是事先105事件到连接110事件的行31和121,它们之间没有任何其他事件,并且所有事件都在相同的类别100中。
只要有效,查询的效率,或者应该组合多少查询并不重要。
更新: 表达问题的简单方法:返回在同一类别中至少存在两个相邻的110s的所有105个
答案 0 :(得分:1)
如果我理解正确,您需要event
为105的行,而id
的两行event
的行select t.*
from sample t
where t.event = 105 and
(select count(*)
from sample t2
where t2.category = t.category and
t2.id > t.category and
t2.category = 110
) = 2;
等于110.如果是这样的话:
group_concat()
编辑:
我认为你可以用select t.category
from sample t
group by t.category
where concat('|', group_concat(event order by id separator '||'), '"') like '%|105|%|110|110|%)
:
{{1}}
然后您可以加入以获取事件为105的详细信息。
答案 1 :(得分:1)
由于缺乏分析函数LAG和LEAD,在MySQL中有点笨拙。
select distinct e105.id
from events e105
join
(
-- all 110 that are directly followed by a110
select just_before.id, just_before.category
from
(
-- all 110 and their direct predecessor
select events.id, min(before.id) as just_before_id
from events
left join events before on before.category = events.category and before.id < events.id
where events.event = 110
group by events.id
) event110
join events just_before on just_before.id = event110.just_before_id and just_before.event = 110
) e110 on e110.category = e105.category and e110.id > e105.id
where events.event = 105
and not exists
(
-- a later occuring 105 still bevor the 110 pair
select *
from events bad105
where bad105.category = e105.category and bad105.id > e105.id and bad105.id < e110.id
);
编辑1:我注意到,你可能需要DISTINCT用于案例105-110-110-112-110-110。两个110对将导致相同的105被发现两次。因为这个原因,我已经在上面添加了DISTICT。我还为要选择的ID添加了限定符e105,因为它丢失了。
编辑2:我也注意到你不需要存在,只能得到最新的105个。你已经拥有了所有105个候选人,你只需要聚合:select distinct max(e105.id)
from events e105
join
(
-- all 110 that are directly followed by a110
select just_before.id, just_before.category
from
(
-- all 110 and their direct predecessor
select events.id, min(before.id) as just_before_id
from events
left join events before on before.category = events.category and before.id < events.id
where events.event = 110
group by events.id
) event110
join events just_before on just_before.id = event110.just_before_id and just_before.event = 110
) e110 on e110.category = e105.category and e110.id > e105.id
where events.event = 105
group by e110.id;