我有一个查询,用于提取用户ID和与每个用户关联的各种事件。由于用户可以拥有多个事件,因此我需要与每个用户关联的第一个事件。 为任何答案添加约束 - 我们的服务器很精细,并且很难处理子查询。
这是初始查询:
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_event_type
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
group by
eid, initial_class
order by eid desc
产生如下结果:
eid contact_created event_time initial_event_type
283916 2015-03-09 10:56:22 2015-03-09 10:57:21 Hot
283916 2015-03-09 10:56:22 2015-03-09 10:56:22 Warm
283914 2015-03-09 10:17:32 2015-03-09 10:17:32 Warm
283912 2015-03-09 10:11:03 2015-03-09 10:11:03 Warm
283910 2015-03-09 09:54:15 2015-03-09 09:54:15 Hot
因此,在这种情况下,用户283916已在结果中返回两次。我想要的只是为这个用户返回一个结果,即initial_event_type所说的" warm"因为那是第一次发生(min event_time)。
这是我的并列。据推测,它可以在功能更强大的服务器上运行,但我们的服务器无法处理子查询 - 这需要很长时间,而且每当我让查询运行时,我们的开发人员都会感到不安。
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_class
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
where concat(e.eid, e.event_time) in ( select concat(eid, min(event_time))
from bm_sets.event378
group by eid)
group by
eid, initial_class
order by eid desc
是否可以在不使用子查询的情况下提取此数据?我之前看到人们在同一张桌子上进行多次连接,我认为这可能是正确的路径,但是,就像我们的服务器一样,我的大脑不够强大,无法弄清楚如何从这条路径开始。
还有其他更有效的解决方案吗?
**以下回答,以下是解释声明的结果:
答案 0 :(得分:1)
是否可以在不使用子查询的情况下提取此数据
您使用子查询的事实不是问题。问题是由于对子查询中的concat(eid, min(event_time)
进行过滤导致,因为此表达式可能没有索引,需要进行表扫描。更好的选择是过滤的子查询:
select
c.id as eid,
c.created as contact_created,
e.event_time,
cs.name as initial_class
from bm_emails.cid378 c
inner join bm_sets.event378 e on e.eid = c.id
inner join bm_config.classes cs on cs.id = e.class_id
where e.event_time = ( select min(event_time)
from bm_sets.event378
WHERE eid = e.eid))
order by eid desc