24. Februar 2012

SQL HAVING ... Kennt jeder, oder?

Everyone knows SQL HAVING ...?

Dieses Blog Posting widme SQL HAVING. Das sieht dann zwar eher nach "SQL Grundkurs" aus, aber mir fällt schon auf, dass HAVING in der Praxis gerne vergessen und durch Subselects "emuliert" wird. Und das muss ja nicht sein. Also machen wir heute ein kurzes, aber einfaches Blog Posting zum Thema HAVING. Wie immer, reicht die Tabelle EMP als Beispiel völlig aus.

select 
  d.dname, 
  sum(e.sal) sal_sum,
  count(e.empno) emp_cnt
from emp e join dept d on (d.deptno = e.deptno)
group by d.dname

DNAME             SAL_SUM    EMP_CNT
-------------- ---------- ----------
ACCOUNTING           8750          3
RESEARCH            10875          5
SALES                9400          6

Nun möchten wir nur die Abteilungen mit mindestens 5 Mitarbeitern haben ... häufig findet man dann diese Lösung, die auch durchaus funktioniert ...

select * from (
  select 
    d.dname, 
    sum(e.sal) sal_sum,
    count(e.empno) emp_cnt
  from emp e join dept d on (d.deptno = e.deptno)
  group by d.dname
) 
where emp_cnt >= 5

DNAME             SAL_SUM    EMP_CNT
-------------- ---------- ----------
RESEARCH            10875          5
SALES                9400          6

Analog geht es natürlich auch mit der WITH-Klausel. Es geht aber auch eleganter, denn für das Filtern auf aggregierten Werten gibt es eben HAVING.

select 
  d.dname, 
  sum(e.sal) sal_sum,
  count(e.empno) emp_cnt
from emp e join dept d on (d.deptno = e.deptno)
group by d.dname
having count(e.empno) > 5

So ... und das war's auch schon für heute ...

Today I'll post about SQL HAVING. This looks a bit like "SQL - Lesson 1", but my observation is that HAVING is very often "emulated" with subqueries or WITH clauses. Using the HAVING clause would make some SQL queries simpler - and for that reason: This short posting is about SQL HAVING . As always, I'll use the well-known table EMP as example.

select 
  d.dname, 
  sum(e.sal) sal_sum,
  count(e.empno) emp_cnt
from emp e join dept d on (d.deptno = e.deptno)
group by d.dname

DNAME             SAL_SUM    EMP_CNT
-------------- ---------- ----------
ACCOUNTING           8750          3
RESEARCH            10875          5
SALES                9400          6

Now we want to have only the departments with more than 5 employees. The following query is quite often being used in such scenarios. And it works fine ...

select * from (
  select 
    d.dname, 
    sum(e.sal) sal_sum,
    count(e.empno) emp_cnt
  from emp e join dept d on (d.deptno = e.deptno)
  group by d.dname
) 
where emp_cnt >= 5

DNAME             SAL_SUM    EMP_CNT
-------------- ---------- ----------
RESEARCH            10875          5
SALES                9400          6

A SQL WITH clause would also work, of course. But the more elegant solution to filter on aggregated values is HAVING.

select 
  d.dname, 
  sum(e.sal) sal_sum,
  count(e.empno) emp_cnt
from emp e join dept d on (d.deptno = e.deptno)
group by d.dname
having count(e.empno) > 5

And that's it ...

Keine Kommentare:

Beliebte Postings