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   &lt;&lt;&lt;&lt;-------<br />      20          5<br />      10          1<br />&nbsp;</p>