Reputation: 952
I have data about phone calls in the form of events which looks something like:
|event_id|call_id|event_type |service|...
|--------|-------|----------------|-------|---
| 1| 1|Call Started |null |
| 2| 1|Recorded Message|null |
| 3| 1|Call at IVR |null |
| 4| 1|Agent Ringing |Sales |
| 5| 1|Agent Answers |Sales |
| 6| 2|Call Started |null |
| 7| 2|Recorded Message|null |
| 8| 2|Call at IVR |null |
| 9| 1|Disconnected |null |
| 10| 1|Call Ended |null |
| 11| 3|Call Started |null |
| 12| 3|Recorded Message|null |
| 13| 2|Agent Ringing |Support|
| 14| 3|Agent Ringing |Sales |
| 15| 2|Agent Answers |Support|
| 16| 3|Agent Answers |Sales |
| 17| 3|Call Hold |null |
| 18| 2|Disconnected |null |
| 19| 2|Call Ended |null |
| 20| 3|Call Retrieved |Sales |
| 21| 3|Disconnected |null |
| 22| 3|Call Ended |null |
I want to select only those events that are associated with a call to Sales
. As you can see, only certain types of event include data in the service
column, which is the the column that I need to filter on. Calls also are not consistent on the number of events they contain due to differences in how they are handled.
I have been filtering the calls in my application by loading all events then using a GroupBy()
on call_id
and finally filtering these groups by selecting any that have any events with service
equalling Sales
.
As in the actual data there is a huge number of calls that I do not want, it would be more efficient to filter this at the database. How would I do this?
Something like
SELECT event_id
FROM events
GROUP BY call_id
HAVING (SELECT COUNT(*) FROM ***this_group*** WHERE service='Sales') > 0
The intended output should be
|event_id|
|--------|
| 1|
| 2|
| 3|
| 4|
| 5|
| 9|
| 10|
| 11|
| 12|
| 13|
| 16|
| 17|
| 20|
| 21|
| 22|
Upvotes: 0
Views: 34
Reputation: 28834
call_id
value(s) which has atleast one row containing service = 'SALES'
.call_id
and get all event_id
value(s)Approach 1: Use a Derived Table
SELECT e1.event_id
FROM events AS e1
JOIN (SELECT DISTINCT e2.call_id
FROM events AS e2
WHERE e2.service = 'SALES') AS dt
ON dt.call_id = e1.call_id
Approach 2: Use a WHERE .. IN(..)
SELECT e2.event_id
FROM events AS e2
WHERE e2.call_id IN (SELECT DISTINCT e1.call_id
FROM events AS e1
WHERE e1.service = 'SALES')
Upvotes: 2
Reputation: 1791
OK, I think what you are looking for is something like the following. I have used the WITH
query to single out the calls you're looking for, and a second query to single out events from these calls.
WITH salesCalls AS (
SELECT call_id, event_type, service
FROM events
WHERE event_type = "Agent Answers"
AND service = "Sales"
GROUP BY call_id, event_type, service
);
SELECT event_id
FROM events
WHERE call_id IN (SELECT call_id FROM salesCalls)
Upvotes: 0
Reputation: 50163
I would use EXISTS
:
SELECT e1.event_id
FROM events e1
WHERE EXISTS (SELECT 1 FROM events e2 WHERE e2.call_id = e1.call_id AND e2.service = 'SALES');
Upvotes: 2