2016-11-03 75 views
-1

我查詢的數據庫(Mysql)女巫來自電話系統,我需要讀取有多少個代理(event_parties.agent_id)登錄到不同的組(event_groups.group_id)。超級複雜的mysql查詢

每次的試劑中,以內部事件被輸入EVENT_ID = 29一個新記錄的組logges,如果註銷EVENT_ID = 30同時在表event_parties出現一個新的條目用相同g_event_id和表示劑的agent_id, 也在表events_groups一個新條目出現與相同g_event_id和GROUP_ID表示第egroup,在輸入/輸出到(表裏面event_groups SAM中劑logges如果代理同時登錄/退出多個組,則e 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天才出來那裏:)

/克里斯蒂安

+1

理想的情況下,如果你可以做一個SQL小提琴,你會做的奇蹟有一個工作組,我們可以測試反對。 – Fallenreaper

+0

好吧,讓我試試SQL小提琴,將填補,在幾分鐘內回來:) – 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,如果登出則設置-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語法風格上的變化:

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