Chapter 05-Reporting Aggregated data Using the Group Functions - 02

Using the GROUP BY Clause

The GROUP BY column does not have to be in the SELECT list.(不过这样一般意义不大)

View Code
SQL> SELECT AVG(salary) AvgSalary FROM employees GROUP BY department_id ORDER BY AVGSALARY;

 AVGSALARY
----------
3475.55556
      4150
      4400
      5760
      6500
      7000
8601.33333
8955.88235
      9500
     10000
     10154

 AVGSALARY
----------
19333.3333

12 rows selected.

Grouping by More than One Column

Using the GROUP BY Clause on Multiple Columns

View Code
SQL> SELECT department_id dept_id,job_id,SUM(salary) FROM employees GROUP BY department_id,job_id ORDER BY dept_id;

   DEPT_ID JOB_ID     SUM(SALARY)
---------- ---------- -----------
        10 AD_ASST           4400
        20 MK_MAN           13000
        20 MK_REP            6000
        30 PU_CLERK         13900
        30 PU_MAN           11000
        40 HR_REP            6500
        50 SH_CLERK         64300
        50 ST_CLERK         55700
        50 ST_MAN           36400
        60 IT_PROG          28800
        70 PR_REP           10000

   DEPT_ID JOB_ID     SUM(SALARY)
---------- ---------- -----------
        80 SA_MAN           61000
        80 SA_REP          243500
        90 AD_PRES          24000
        90 AD_VP            34000
       100 FI_ACCOUNT       39600
       100 FI_MGR           12008
       110 AC_ACCOUNT        8300
       110 AC_MGR           12008
           SA_REP            7000

20 rows selected.

lllegal Queries Using Group Functions

  • Any column or expression in the SELECT list that is not an aggregate function must be in the GROUP BY clause:
View Code
SQL> SELECT department_id,count(last_name) FROM employees;
SELECT department_id,count(last_name) FROM employees
       *
ERROR at line 1:
ORA-00937: not a single-group group function

Solution:A GROUP BY clause must be added to count the last names for each department_id.

View Code
SQL> SELECT department_id,job_id,count(last_name) FROM employees GROUP BY department_id;
SELECT department_id,job_id,count(last_name) FROM employees GROUP BY department_id
                     *
ERROR at line 1:
ORA-00979: not a GROUP BY expression

Solution:Either add job_id in the GROUP BY or remove the job_id column from the SELECT list.

You cannot use the WHERE clause to restrict groups.

You use the HAVING clause to restrict groups.

You cannot use group functions in the WHERE clause.

SQL> SELECT department_id,AVG(salary) FROM employees WHERE AVG(salary) > 8000 GROUP BY department_id;
SELECT department_id,AVG(salary) FROM employees WHERE AVG(salary) > 8000 GROUP BY department_id
                                                      *
ERROR at line 1:
ORA-00934: group function is not allowed here

分析原因:在上面的SQL中,Oracle server的查询执行顺序是:首先执行WHERE AVG(salary),然后执行GROUP BY department_id,再执行SELECT department_id,AVG(salary)

Solution:

View Code
SQL> SELECT department_id,AVG(salary) FROM employees GROUP BY department_id HAVING AVG(salary) > 8000 ORDER BY department_id;

DEPARTMENT_ID AVG(SALARY)
------------- -----------
           20        9500
           70       10000
           80  8955.88235
           90  19333.3333
          100  8601.33333
          110       10154

6 rows selected.

Restricting Group Results with the HAVING Clause

When you use the HAVING clause,the Oracle server restricts groups as follows:

1、Rows are grouped.

2、The group function is applied.

3、Groups matching the HAVING clause are displayed.

Using the HAVING Clause

View Code
SQL> SELECT department_id,MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary) > 8000 ORDER BY department_id;

DEPARTMENT_ID MAX(SALARY)
------------- -----------
           20       13000
           30       11000
           50        8200
           60        9000
           70       10000
           80       14000
           90       24000
          100       12008
          110       12008

9 rows selected.
View Code
SQL> SELECT job_id,SUM(salary) PAYROLL FROM employees WHERE job_id NOT LIKE '%REP%' GROUP BY job_id HAVING SUM(salary)>13000 ORDER BY SUM(salary);

JOB_ID        PAYROLL
---------- ----------
PU_CLERK        13900
AD_PRES         24000
IT_PROG         28800
AD_VP           34000
ST_MAN          36400
FI_ACCOUNT      39600
ST_CLERK        55700
SA_MAN          61000
SH_CLERK        64300

9 rows selected.

Oracle Server SQL执行顺序图解:

Nesting Group Functioins

Display the maximum average salary:

View Code
SQL> SELECT MAX(AVG(salary)) MAZ_SALARY,MIN(AVG(salary)) FROM employees GROUP BY department_id;

MAZ_SALARY MIN(AVG(SALARY))
---------- ----------------
19333.3333       3475.55556

Summary

In this lesson,you should have learned how to:

  • Use the group functions COUNT,MAX,MIN,SUM,and AVG
  • Write queries that use the GROUP BY clause
  • Write queries that use the HAVING clause
SELECT column,group_fuction

FROM table

[WHERE conditions]

[GROUP BY group_by_expression]

[HAVING group_condtion]

[ORDER BY column]

注意:精通上述6大子句的执行顺序

 

 

posted @ 2013-04-15 12:28  ArcerZhang  阅读(211)  评论(0编辑  收藏  举报