MYSQL自连接基于MAX获取行并具有

时间:2016-12-07 09:27:40

标签: mysql sql select self-join having

我需要从2个表中计算COUNT行,并且只获得g_event_id events.event_id IN (30, 31, 32, 33)行的最高行数。仅在events.event_id为30-33的帐户中占用行数。

SQL小提琴:Fiddle

我的桌子:

 CREATE TABLE event_parties
 (`g_event_id` int, `agent_id` int)
;

INSERT INTO event_parties
(`g_event_id`, `agent_id`)
VALUES
(2917, '2'),
(2918, '2'),
(2919, '2'),
(3067, '3'),
(3078, '3'),
(3079, '1'),
(3082, '1'),
(3917, '2'),
(3918, '2'),
(3919, '2'),
(4067, '3'),
(4078, '3'),
(4079, '1'),
(5067, '3'),
(5078, '3'),
(5079, '1'),
(6067, '3'),
(6078, '3'),
(6079, '1'),
(7067, '3'),
(7078, '3'),
(7079, '1'),
(8067, '3'),
(8078, '3'),
(8079, '1')

;
CREATE TABLE events
(`g_event_id` int, `event_id` int, `event_time` datetime)
;

INSERT INTO events
(`g_event_id`, `event_id`, `event_time`)
 VALUES
(2917, '29', '2016-10-19 15:24:25'),
(2918, '31', '2016-10-19 15:24:28'),
(2919, '21', '2016-10-19 15:29:46'),
(3067, '29', '2016-10-20 15:33:46'),
(3078, '23', '2016-10-21 15:29:46'),
(3079, '29', '2016-10-20 15:34:46'),
(3082, '30', '2016-10-21 15:42:46'),
(3917, '29', '2016-10-19 15:24:25'),
(3918, '31', '2016-10-19 15:24:28'),
(3919, '21', '2016-10-19 15:29:46'),
(4067, '29', '2016-10-20 15:33:46'),
(4078, '23', '2016-10-21 15:29:46'),
(4079, '29', '2016-10-20 15:34:46'),
(5067, '29', '2016-10-20 15:33:46'),
(5078, '23', '2016-10-21 15:29:46'),
(5079, '29', '2016-10-20 15:34:46'),
(6067, '29', '2016-10-20 15:33:46'),
(6078, '23', '2016-10-21 15:29:46'),
(6079, '29', '2016-10-20 15:34:46'),
(7067, '29', '2016-10-20 15:33:46'),
(7078, '23', '2016-10-21 15:29:46'),
(7079, '29', '2016-10-20 15:34:46'),
(8067, '29', '2016-10-20 15:33:46'),
(8078, '23', '2016-10-21 15:29:46'),
(8079, '29', '2016-10-20 15:34:46')

;

选择是为了给我一个Callcenter代理的状态,我想计算每个状态(event_id)中有多少个代理(agent_id)。由于表“事件”只是代理的事件,我只需要计算每个agent_id的最新值(具有最高值)g_event_id,而棘手的部分是我只想计算event_id IN(30,31,32,32, 33)。 所以基本上,为每个agent_id选择具有最高g_event_id(和event_id IN(30,31,32,33))的行。 我需要在这两个表之间使用g_event_id作为ID来加入。字段g_event_id是键,只出现一次。我需要表events中的所有字段,我需要最高g_event_id或最高event_time的行。 像这样:

event_id   N_events
--------   ----------
    31         1
    30         1

到目前为止我有这个选择:

SELECT event_id,
COUNT(events.event_id) AS N_events
FROM event_parties 
INNER JOIN events USING (g_event_id)
LEFT JOIN event_parties AS later_event
ON (later_event.agent_id = event_parties.agent_id 
  AND later_event.g_event_id > event_parties.g_event_id)
WHERE later_event.g_event_id IS NULL AND event_parties.agent_id != 0 AND     events.`event_id` IN (30,31,32,33)
GROUP BY events.event_id

上面这个选择的问题是它只会给我最高g_event_id的行,我想只选择events.event_id =(30,31,32,33)的行然后计数最高g_event_id

的行

尝试在GROUP(having)之后使用HAVING events.event_id IN (30,31,32,33)但没有任何成功。

1 个答案:

答案 0 :(得分:1)

此查询应该为您提供结果:

select e.event_id, count(stats.agent_id) as N_count
from (
  select max(p.g_event_id) as g_event_id, p.agent_id
  from events e 
  join event_parties p
  on e.g_event_id = p.g_event_id
  where e.event_id in (30,31,32,33)
  group by p.agent_id
) as stats
join events e
on e.g_event_id = stats.g_event_id
group by e.event_id;

内部查询(stats)首先检索每个代理的最新相关状态:对于每个g_event_id,它将获得最大agent_idevent_id范围(每个代理最多一行)。

然后它会与events - 表结合,以检索此event_id的实际g_event_id;然后它计算每event_id个代理的数量。

正如评论中所述,这假设g_event_id是两个表的主键(但尤其是events),并且最新状态由最大g_event_id给出},而不是event_time