Question

In short I have 2 tables:

USERS:

------------------------
UserID   |   Name
------------------------
0     a
1     b
2     c

CALLS:
------------------------
ToUser   |   Result
------------------------
0     ANSWERED
1     ENGAGED
1     ANSWERED
0     ANSWERED

Etc, etc (i use a numerical referance for result in reality)

I have over 2 million records each detailing a call to a specific client. Currently I'm using Case statements to count each recurance of a particular result AFTER I have already done the quick total count:

COUNT(DISTINCT l_call_log.line_id),
COALESCE (SUM(CASE WHEN l_call_log.line_result = 1 THEN 1 ELSE NULL END), 0) AS [Answered],
COALESCE (SUM(CASE WHEN l_call_log.line_result = 2 THEN 1 ELSE NULL END), 0) AS [Engaged], 
COALESCE (SUM(CASE WHEN l_call_log.line_result = 4 THEN 1 ELSE NULL END), 0) AS [Unanswered]

Am I doing 3 scans of the data after my inital total count? if so, is there a way I can do one sweep and count the calls as-per-result in one go?

Thanks.

Was it helpful?

Solution

This would take one full table scan.

EDIT: There's not enough information to answer; because the duplicate removal (DISTINCT) that I missed earlier, we can't tell what strategy that would be used.... especially without knowing the database engine.

In just about every major query engine, each aggregate function is executed per each column per each row, and it may use a cached result (such as COUNT(*) for example).

Is line_result indexed? If so, you could leverage a better query (GROUP BY + COUNT(*) to take advantage of index statistics, though I'm not sure if that's worthwhile depending on your other tables in the query.

OTHER TIPS

There is the GROUP BY construction in SQL. Try:

SELECT COUNT(DISTINCT l_call_log.line_id)
  GROUP BY l_call_log.line_result

I would guess it's a table scan, since you don't have any depending subqueries. Run explain on the query to be sure.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top