views:

59

answers:

3

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

ect ect (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.

A: 

There is the GROUP BY construction in SQL. Try:

SELECT COUNT(DISTINCT l_call_log.line_id)
  GROUP BY l_call_log.line_result
David Crawshaw
yeah, i use group by as standard. in this instance i group by USERID, my resulting table is essentially user | totalcount | answeredcount | engagedcount | unansweredcount
Sean.C
A: 

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

PatrikAkerstrand
A: 

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.

Alex Papadimoulis
I tried making an in function index for the result but it made no differance in the IDE - it still times out. Its interesting to know it takes one scan to complete all 3 expressions though.. thinking about about it, would it do one scan to group the calls via user (inital count) and then another scan per user to count the results?
Sean.C
Drat. I missed the DISTINCT part of your query; that changes things.
Alex Papadimoulis
Thanks anyway Alex i think you have set me on the right track, or at least the right way of thinking to improve this.
Sean.C