Is this a bug in Analytical Functions? NULL is supposed to be UNEQUAL to NULL?
While presenting the 7Up Training – upgrading experienced Oracle developers from their Oracle 7 base of knowledge and experience ("still writing 7 backwards compatible code against a 10g database") to 10g, we ran into a funny little example with the Oracle Analytical SQL Functions – that also applies to standard GROUP BY operations by the way – that suggests that NULL == NULL in some circumstances. To be fair: it feels (intuitively) correct. but theoretically (what do you say Toon??) it is a little fishy I think.

The situation is very simple: I have updated my EMP table to have several employees without department. Then I queried to find out for each employee his name, department, salary and the percentage of the total salary sum within the department allocated to the employee. The query is straightforward:
select ename<br />, deptno<br />, sal<br />, ratio_to_report(sal) <br /> over ( partition by deptno) <br /> sal_percentage<br />from emp<br />order<br />by 2, 4 <br />
The data in EMP shows two employees without Department (i.e. their DEPTNO is NULL). The results of this query show the two employees without department – MILLER and KING – as having 20 respectively 80 percent of the total salary sum in their department (the partition of all employees with the same DEPTNO). However, their DEPTNO is NULL and since NULL is never equal to NULL, there are no other employees with the same DEPTNO. Or are there?
ENAME DEPTNO SAL SAL_PERCENTAGE<br />---------- ---------- ---------- --------------<br />CLARK 10 2695 1<br />SMITH 20 800 .071604386<br />ADAMS 20 1100 .09845603<br />SCOTT 20 3000 .268516447<br />FORD 20 3000 .268516447<br />JONES 20 3272.5 .292906691<br />JAMES 30 950 .09808983<br />MARTIN 30 1250 .129065565<br />WARD 30 1250 .129065565<br />TURNER 30 1500 .154878678<br />ALLEN 30 1600 .165203924<br />BLAKE 30 3135 .323696438<br />MILLER 1300 .200896307<br />KING 5171 .799103693 <br />
On further analysis – something I apparently never actively realized – the classic GROUP BY does the exact same thing:
select deptno<br /> , count(*) <br /> from emp <br /> group <br /> by deptno<br />
The results also suggest an equality between NULL…
<p> DEPTNO COUNT(*)<br />-------- ----------<br /> 30 6<br /> 2 <<<<-------<br /> 20 5<br /> 10 1<br /> </p>
Oracle is just following the rules layed out by ANSI SQL.