2016-11-03 4 views
-1

데이터베이스 (Mysql) 마녀 나는 전화 통신 시스템에서 온다, 나는 얼마나 많은 에이전트 (event_parties.agent_id)가 다른 그룹 (event_groups.group_id)에 로그인되어 있는지 읽어야한다.매우 복잡한 mysql 쿼리

상담원이 새 레코드 한 event_id = 29이벤트 내부 테이블을 입력하는 그룹에 logges 때마다, 만약 동시에 로그 아웃 한 event_id = 30 테이블 event_parties 나타납니다에서 새 항목 동일한과 는 제 egroup 나타내는도 표 새로운 엔트리 을 g_event_id 동일한 함께 표시 events_groups을 및 에이전트를 나타내는 AGENT_ID, 을 g_event_id 및 GROUP_ID 그/아웃 테이블 안에 샘 event_groups (행에서 에이전트 logges 에이전트가 동시에 여러 그룹에 로그인/로그 아웃하는 경우 e_event_id는 둘 이상의 항목에 대해 동일 할 수 있습니다.

그래서 내 생각은 내가에서 에이전트 로그인과 같은 event_groups.group_id과 같은 event_parties.agent_id과 events.event_id 어떠한 새로운 항목 (EVENT_TIME)가없는 모든 레코드를 선택하여 GROUP_ID (29)를 사이에받을 수 있다는 것입니다 및 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 천재가있다 거기 :

/크리스티안

+1

이상적으로, 당신은 경이를 할 것이라고는이 우리에 대해 테스트 할 수 있습니다 작업 집합이 있습니다. – Fallenreaper

+0

자, SQL Fiddle을 사용해 보도록하겠습니다. 몇 분 후에 다시 돌아 오십시오 :) – Kristian

답변

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 

Link to SQL Fiddle

원하는 데모가 지금 날을 취소합니다. 모든 에이전트/그룹 조합에 대해, 로그인의 경우 전환 수를 설정하고 로그 아웃하면 전환 수를 -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를 사용

Link to SQL Fiddle


FWIW 구문 스타일의 변화 : 당신은 SQL 바이올린을 만들 수 있다면

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; 
+0

정말 놀랍습니다! – Kristian

+0

마지막 쿼리가 나를 위해 완벽하게 작동합니다. 시작 레코드가 안정적이지 않습니다. :) – Kristian

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