It appears that when using a having clause a count(*) is evaluated before the having but the number of rows returned is evaluated after. The fix is probably sub-queries but if it’s possible to avoid it I’d like to. I’m using count(*) to avoid no_data_found.
This behaviour occurs in 11.2.0.1.0, 10.2.0.1.0, 9.2.0.7.0 so it’s obviously intended but I don’t quite understand why. An easily replicable example is below.
Does anyone know why this happens? I would have expected the count(*) to return 1.
create table tmp_test1 as
select level as id, level as val
from dual
connect by level <= 1000
;
Table created.
create table tmp_test2 as
select level as id, level as val
from dual
connect by level <= 1000
;
Table created.
select count(*) as count
from tmp_test1 a
join tmp_test2 b
on a.id = b.id
having max(a.val) = max(b.val)
;
COUNT
----------
1000
select 1 as num_rows
from tmp_test1 a
join tmp_test2 b
on a.id = b.id
having max(a.val) = max(b.val)
;
NUM_ROWS
----------
1
The
havingclause operates at the group level – where no group by is specified, this means that it is operating across the entire dataset.This means that in any query with a
havingclause and nogroup byclause, the results can only return 0 rows (if thehavingcondition is false) or 1 row (if thehavingcondition is true).