Lab 3 – Aggregate Functions, Group By and Having Clauses
1. AGGREGATE FUNCTIONS
In all the examples so far, we have selected values stored in each row of a table (like SAL), or values calculated for each row (like SAL*12). That is, we have selected information about individual rows stored in the database. You can also select “summary” information about groups of rows in the database.
Oracle provides five aggregate functions (or group functions) that can be applied to data retrieved in a query:
AVG Computes the average value SUM Computes the total value MIN Finds the minimum value MAX Finds the maximum value COUNT Counts the number of values
1.1 Selecting Summary Information From One Group
As shown below, the column that the function is applied to must be enclosed in parentheses.
Find the average salary for clerks (group.1) SQL > SELECT AVG(SAL)
2 FROM EMP
3 WHERE JOB = ‘CLERK’;
Oracle uses all the rows that satisfy the search-condition (WHERE JOB= ‘CLERK’) to compute the summary information. Rather than displaying a value (SAL) for each individual row (CLERK) selected, Oracle calculates a single value – AVG(SAL) – as a result.
You can have more than one group function in a SELECT clause.
Find the total salary and total commission for salesmen (group 2) SQL > SELECT SUM(SAL), SUM(COMM)
2 FROM EMP
3 WHERE JOB = ‘SALESMAN’;
You can use group functions in arithmetic expressions.
Compute the average annual salary plus commission for all salesmen (group 3). SQL > SELECT AVG(SAL + COMM)*12
2 FROM EMP
3 WHERE JOB = ‘SALESMAN’;
Find the highest and lowest paid employee salaries and the difference between them (group 4).
SQL > SELECT MAX(SAL), MIN(SAL), MAX(SAL)-MIN(SAL) 2 FROM EMP;
You can use group functions with arithmetic or string functions.
Find the number of characters in the longest department name (group 5). SQL > SELECT MAX(LENGTH(DNAME))
2 FROM DEPT;
1
In standard SQL, you may NOT have both aggregates and non-aggregates in the same SELECT list. For example, SELECT ENAME, AVG(SAL) is an error. This is because ENAME is an attribute of a each row selected and AVG(SAL) is an attribute of all the rows selected. So if you want to find the name and salary of the employee (or employees) who receive the maximum salary, you cannot use the above query. Instead, you should use a sub-query as in the following example.
Find the name and salary of the employee (or employees) who receive the maximum salary (group 6).
SQL > SELECT ENAME, JOB, SAL 2 FROM EMP
3 WHERE SAL =
4 (SELECT MAX(SAL) FROM EMP);
The COUNT function can be used to count the number of values, number of distinct values, or number of rows selected by the query.
Count the number of employees who receive a commission (group 7) SQL > SELECT COUNT (COMM)
2 FROM EMP;
COUNT may be used with the keyword DISTINCT to return the number of different values stored in the column. That is, duplicate values are eliminated before values are counted.
Count the number of different jobs held by employees in department 30 (group.8)
SQL > SELECT COUNT(DISTINCT JOB) 2 FROM EMP
3 WHERE DEPTNO = 30;
Count the number of employees in department 30 (group. 9) SQL > SELECT COUNT (*)
2 FROM EMP
3 WHERE DEPTNO = 30;
2 SELECTING SUMMARY INFORMATION FROM GROUPS – GROUP BY
Let’s say you want to know the average salary for the employees in department 10, department 20 and department 30. You could solve this problem with the following three queries:
Find the average salary of the employees in each department. SQL > SELECT AVG (SAL)
2 FROM EMP
3 WHERE DEPTNO = 10; SQL > SELECT AVG (SAL)
2 FROM EMP
3 WHERE DEPTNO = 20; SQL > SELECT AVG (SAL)
2 FROM EMP
3 WHERE DEPTNO = 30;
2
The same information could be returned by a single query with a GROUP BY clause. The GROUP BY clause divides a table into groups of rows with matching values in the same column (or columns).
List the department number and average salary of each department (group.10) SQL > SELECT DEPTNO, AVG(SAL)
2 FROM EMP
3 GROUP BY DEPTNO;
In the above query, all the employees are divided into groups based on their department number (GROUP BY DEPTNO). Thus, there are three different groups: the employees in department 10, the employees in department 20 and the employees in department 30. The group functions AVG(SAL) is then applied to all the rows in each group.
When you have a GROUP BY clause you can select the group column in addition to group functions. This is because the grouping column is an attribute of the group (all the rows of the group have the same value for the grouping column).
The GROUP BY clause always follows the WHERE clause, or the FROM clause when there is no WHERE clause in the command.
Find each department’s average annual salary for all its employees except the managers and the president (group. 11).
SQL > SELECT DEPTNO, AVG(SAL)*12 2 FROM EMP
3 WHERE JOB NOT IN (‘MANAGER’, ‘PRESIDENT’) 4 GROUP BY DEPTNO;
You can partition rows of a table into groups based on the values in more than one column.
Divide all employees into groups by department, and by jobs within department. Count the employees in each group and compute each group’s average annual salary. (group. 12)
SQL > SELECT DEPTNO, JOB, COUNT(*), AVG(SAL)*12 2 FROM EMP
3 GROUP BY DEPTNO, JOB;
In the example above, a group is formed for every job within every department (GROUP BY DEPTNO, JOB). Look at the last row of the query result. This group of department 30 salesmen has a count of 4 and an average salary of $16,800.
You can have join-conditions and group functions in the same query.
Issue the same query as above except list the department name rather than the department number (group. 13)
SQL > SELECT DNAME, JOB, COUNT(*), AVG(SAL)*12 2 FROM EMP, DEPT
3 WHERE DEPT.DEPTNO = EMP.DEPTNO
4 GROUP BY DNAME, JOB;
3 SPECIFYING A SEARCH-CONDITION FOR GROUPS – HAVING
You can specify search-conditions for groups just as you can specify conditions for individual rows. As you know, search-conditions for individual rows are specified in the WHERE clause, for groups, you should use HAVING clause to do specification.
3