Reputation:
I have been looking for a solution to this seemingly simple problem. The query only breaks when I introduce the last sum() function in the where clause. I get the error "Error Code: 1111. Invalid use of group function." I can't figure out why it won't allow me to make this one where statement.
Query
select
dIntervalStart,
weekofyear(dIntervalStart) WeekOfYear,
weekday(dIntervalStart) DayOfWeek,
cast(dIntervalStart as time) IntervalStart,
sum(nExternToInternAcdCalls) CallVolume
from
iwrkgrpqueuestats
where
SiteId = 1
and cname in ('applications' , 'employer',
'factfind',
'general',
'other')
and cReportGroup = '*'
and CAST(dIntervalStart as time) between '07:00' and '17:30'
and weekday(dIntervalStart) not in (5 , 6)
and sum(nExternToInternAcdCalls) <> 0
group by weekofyear(dIntervalStart) , weekday(dIntervalStart) , cast(dIntervalStart as time)
order by IntervalStart asc, dIntervalStart desc
Upvotes: 1
Views: 763
Reputation: 108370
Relocate the predicate on the aggregate expression to the HAVING
clause, e.g.:
GROUP BY ...
HAVING sum(nExternToInternAcdCalls) <> 0
ORDER BY ...
The predicates in the WHERE clause are evaluated when rows are accessed, they pick out which rows are included. The value of the aggregate expression (e.g. SUM(foo)
) isn't available when the rows are accessed. The value for that expression can't be determined until after the rows are accessed.
The predicates in the HAVING
clause are applied after the rows are accessed, and after the resultset is prepared. When the HAVING predicates are evaluated, the aggregate (SUM(foo)
) will be available.
NOTE: the GROUP BY
clause would typically include all of the non-aggregate expressions in the SELECT list. MySQL is more relaxed than other databases, which can be both a blessing and a curse; if the GROUP BY "collapses" rows, for non-aggregates in the SELECT list, MySQL returns a value from one of the rows.
That is, if you GROUP BY weekofyear(foo)
, and return foo
in the SELECT list, and there are multiple rows with foo values that evaluate to the same weekofyear(foo)
value, MySQL will return one row for the given weekofyear(foo)
and also return one of the foo values from one of the rows. Other databases (Oracle, SQL Server, et al.) would throw an error rather than returning a resultset.
Upvotes: 2
Reputation: 1366
You cannot use group by
like this, group by is used to distinct result and and specify the element of reference of aggregate functions
Try this :
select
dIntervalStart,
weekofyear(dIntervalStart) WeekOfYear,
weekday(dIntervalStart) DayOfWeek,
cast(dIntervalStart as time) IntervalStart,
sum(nExternToInternAcdCalls) CallVolume
from
iwrkgrpqueuestats
where
SiteId = 1
and cname in ('applications' , 'employer',
'factfind',
'general',
'other')
and cReportGroup = '*'
and CAST(dIntervalStart as time) between '07:00' and '17:30'
and weekday(dIntervalStart) not in (5 , 6)
and sum(nExternToInternAcdCalls) <> 0
group by dIntervalStart,
WeekOfYear,
DayOfWeek,
IntervalStart --columns not using aggregate functions
order by IntervalStart asc, dIntervalStart desc
Upvotes: 0