我查询的数据库(Mysql)来自电话系统,我需要读取有多少代理(event_parties.agent_id)被记录到不同的组(event_groups.group_id)。
每次代理登录到某个组时,如果注销 event_id = 30 event_id = 29 的事件表中输入新记录>同时,表 event_parties 中的新条目与 g_event_id 相同,agent_id代表代理, 同样在表 events_groups 中,新条目显示为具有相同的 g_event_id ,group_id表示代理登入/注销的组合(在表event_groups内,相同的g_event_id可能相同)如果代理同时登录/注销多个组,则可以有多个条目。
所以我的想法是我可以通过选择所有没有较新条目(event_time)且具有相同event_groups.group_id和相同event_parties.agent_id并且events.event_id介于29和之间的记录来获取登录代理和group_id。 30.
events.event_id = 29表示代理登录。
events.event_id = 30表示代理注销。
设计这样一个mysql选择时遇到了一些严重困难:(
以下是每个表格中的一些示例数据。
表:
的事件
g_event_id event_id event_time
---------- -------- ----------
7816 31 2016-11-03 09:46:18
7815 30 2016-11-03 09:45:18
7814 31 2016-11-03 09:44:18
7813 29 2016-11-03 09:43:18
7812 30 2016-11-03 09:42:18
7811 29 2016-11-03 09:41:18
7810 31 2016-11-03 09:40:18
7809 29 2016-11-03 09:39:18
7808 31 2016-11-03 09:38:18
7807 7 2016-11-03 09:37:18
7806 29 2016-11-03 09:36:18
7805 30 2016-11-03 09:35:18
7804 30 2016-11-03 09:34:18
7803 29 2016-11-03 09:33:18
7802 29 2016-11-03 09:32:18
表: 的 event_parties
g_event_id agent_id
---------- --------
7816 1
7815 1
7814 1
7813 1
7812 1
7811 1
7810 2
7809 2
7808 2
7807 3
7806 3
7805 3
7804 3
7803 3
7802 3
表: event_groups
g_event_id group_id
---------- --------
7816 1
7815 1
7814 1
7813 1
7813 2
7813 3
7813 4
7812 1
7811 1
7810 1
7809 1
7808 1
7807 1
7806 1
7806 3
7805 4
7804 1
7804 2
7803 4
7802 1
7802 2
从上表中我希望我的select语句结果为:
group_id agent_id
-------- --------
4 1
3 1
2 1
1 2
1 3
3 3
这样的查询是否可行,是否有任何sql天才:)
/克里斯蒂安
答案 0 :(得分:2)
SELECT group_id, agent_id
FROM (SELECT agent_id, eg.group_id, if(event_id = 29, 1, -1) AS transitions
FROM event_parties ep
JOIN `events` e ON ep.g_event_id = e.g_event_id
JOIN event_groups eg ON ep.g_event_id = eg.g_event_id
WHERE e.event_id IN (29, 30)) AS t
GROUP BY agent_id, group_id
HAVING sum(transitions) > 0
ORDER BY agent_id, group_id DESC
我认为这会做你所说的。对于每个代理/组合,如果它们登录,则将转换数设置为1,如果它们注销,则设置为-1。查看整个数据集,如果他们已登录然后注销,则特定代理组的总和将为0,这将在外部查询中计算。
这取决于不从特定代理/组合的注销事件开始。如果您正在查看的数据集以注销事件开始,则用户将永远不会被注销。
或者,你可以通过查看最后一条记录得出相同的结果,并确定它是29还是30,并且只显示那些29。
SELECT group_id, agent_id
FROM (SELECT agent_id, group_id, max(e.g_event_id) AS last_event_id
FROM event_parties ep
JOIN `events` e ON ep.g_event_id = e.g_event_id
JOIN event_groups eg ON ep.g_event_id = eg.g_event_id
WHERE e.event_id IN (29, 30)
GROUP BY agent_id, group_id) AS last_event
JOIN `events` e ON e.g_event_id = last_event.last_event_id
WHERE e.event_id = 29;
这更少依赖于你在系列中的开始位置,但是连接稍微复杂一些。
使用natural join
更改FWIW语法样式:
select group_id, agent_id
from ( select agent_id, group_id,
max( g_event_id ) as g_event_id
from event_parties natural join `events` natural join event_groups
where event_id in (29, 30)
group
by agent_id, group_id ) as last_event
natural join `events`
where event_id = 29;
答案 1 :(得分:0)
我现在做一个演示,然后告诉我你想要什么
select g.group_id,p.agent_id from event_groups g
join event_parties p on g.g_event_id=p.g_event_id
join events e on p.g_event_id =e.g_event_id where e.event_id=29