【问题标题】:MYSQL self join get row based on MAX and havingMYSQL 自连接获取基于 MAX 的行并具有
【发布时间】:2016-12-07 09:27:40
【问题描述】:

我需要对 2 个表中的行进行计数,如果 events.event_id IN (30, 31, 32, 33),则只获取具有最高 g_event_id 的行。仅考虑 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')

;

选择是假设给我一个呼叫中心代理的状态,我想计算每个状态(event_id)中有多少代理(agent_id)。由于表“事件”只是代理的事件,我只需要计算每个代理 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 events.event_id IN (30,31,32,33)) 之后使用 having,但没有成功。

【问题讨论】:

  • 小提琴对我不起作用,所以我无法检查:g_event_id 是您的主键吗?我认为不是,否则您的计数将是 1 或 0,对吗?此外,您的选择列表(4 列)不适合您请求的结果(2 列)或您的 group by(1 列 + 1 个计数)。另外,我不太明白您所说的“我需要具有最高 g_event_id 或最高 event_time 的行”是什么意思 - 这可能描述了 2 行,您想要哪一行?那么:您能否从该数据中添加您想要的确切结果?以及更清晰的示例数据(例如超过 1 个相同的 g_event_id)和表?
  • 更新了 Fiddle [链接] (sqlfiddle.com/#!9/b16f66/6)。上面还更新了更多数据。选择是假设给我一个呼叫中心代理的状态,我想计算每个状态(event_id)中有多少代理(agent_id)。由于表“事件”只是代理上的事件,我只需要计算每个代理的最新 event_id,而棘手的部分是我只想计算 event_id IN (30, 31, 32, 32, 33) 的位置
  • 您仍然没有回答重要问题:每个g_event_id 是否可以有超过 1 行(这就是“更多数据”应该显示的内容),以及您期望的确切结果集您提供的数据(因为您的描述仍然不够清楚)。
  • 抱歉,g_event_id 是主键(每个 g_event_id 只有一行)。我想要的确切结果是: event_id N_events -------- ---------- 31 1 30 1
  • 我想我还是没抓住重点。如果g_event_id是主键,那么最多有一行g_event_id最高。由于您甚至不希望结果中出现该 id,您可以简单地查询 SELECT distinct event_id, 1 AS N_events FROM event_parties INNER JOIN events USING (g_event_id) WHERE events.event_id IN (30,31,32,33);。如果活动中的每一行都肯定有派对中的一行,您甚至可以删除join

标签: mysql sql select self-join having


【解决方案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)首先检索每个代理的最新相关状态:它将为每个agent_id 获得最大的g_event_idevent_id 在给定范围内(因此最多一行每个代理)。

然后它将与events-table 连接以检索此g_event_id 的实际event_id;然后它计算每个event_id 的代理数。

根据 cmets 的计算,这假定 g_event_id 是两个表的主键(尤其是 events),并且最新状态由最大的 g_event_id 给出,而不是 @987654333 @。

【讨论】:

    猜你喜欢
    • 2017-03-03
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    相关资源
    最近更新 更多