You are on page 1of 8

School of Computing, Engineering and Information Sciences

University of Northumbria

SQL Subqueries
Aim:
To practise the use of SQL subqueries of various kinds and for a variety of
purposes.

Outline of Session:
Execute CREATE TABLE, INSERT, DELETE and UPDATE statements with
subqueries.
Carry out queries that involve comparisons of single value subquery results,
where those subqueries are :
simple,
correlated.
Carry out queries that involve comparisons of multiple value subquery results,
where those subqueries are :
simple,
correlated.
Carry out queries that involve nested subqueries.
School of Computing, Engineering and Information Sciences
University of Northumbria

SUBQUERIES IN STATEMENTS THAT MANAGE THE DB’S CONTENTS


Create a new table in the DB with the following statement : -

SQL> CREATE TABLE DEPT_STAFF


2 AS
3 SELECT *
4 FROM EMP NATURAL JOIN DEPT ;

Check the structure and contents of DEPT_STAFF.

Execute the following statement :-

SQL> INSERT INTO DEPT_STAFF


2 SELECT * FROM DEPT_STAFF;

Exercise:
Does this statement work ? Should it ? Why (not) ?

What are the contents of DEPT_STAFF now ?

What can you deduce from this ?

Execute the following statement :-

SQL> DELETE FROM DEPT_STAFF


2 WHERE DEPT_NO =
3 (SELECT DEPT_NO FROM DEPT
4 WHERE DEPT_NAME = 'Production');

Exercise:
What does this statement accomplish ?

Does this statement accomplish what it should ?

2
School of Computing, Engineering and Information Sciences
University of Northumbria

Suppose we want to give all our department managers a pay increase equal to 10% of
their department’s budget. The update could be as follows :-

SQL> UPDATE DEPT_STAFF


2 SET SALARY = SALARY +
3 (SELECT BUDGET/10 FROM DEPT
4 WHERE DEPT.MANAGER_NO = DEPT_STAFF.EMP_NO) ;

Exercise:
Execute this statement, and check its result.
Explain exactly what the update did. Was the subquery correlated or not ?

Did it accomplish what we wanted ? Why (not) ?

Table DEPT_STAFF is now full of rubbish data. Besides, its contents originally
duplicated data that was held in other DB tables, which is not sensible.
So get rid of DEPT_STAFF !!

QUERIES WITH SINGLE VALUE SUBQUERY COMPARISONS


Example : find the details of the department managed by the employee Brown :-

SQL> SELECT * FROM DEPT


2 WHERE MANAGER_NO =
3 (SELECT EMP_NO FROM EMP
4 WHERE EMP_NAME = 'Brown');

Exercise:
Execute the above query.
Write an equivalent query that does not use a subquery. Check you get the same result.

Example : get the department names and budgets for those departments whose budget is
less than the average :-

3
School of Computing, Engineering and Information Sciences
University of Northumbria

SQL> SELECT DEPT_NAME, BUDGET


2 FROM DEPT
3 WHERE BUDGET <
4 (SELECT AVG( BUDGET ) FROM DEPT);

Exercise:
Execute the above example query.
Design and execute queries to handle the following :
1. Which employees have a below average salary?
2. Which employees have a greater than average salary?
3. Which employees are paid exactly the avarage salary ?
4. Which employee is the most highly paid ?
5. Which employee is paid the least ?
6. Whose salary exceeds the lowest salary by more than £4,000 ?

Exercise: write a query to find which employees work on exactly one project ?

What is the difference between the subquery used here and those used in the previous set of queries ?

Exercise: develop and execute queries to handle the following :

1. Get the names of departments that have only one employee.


2. Get the deadlines of projects that have more than 3 employees working on them.
3. Get the names of employees who work in departments such that their salary is less than 10% of their
department’s budget.

Consider the following example, which is looking for the names of all employees whose
salary is greater than 40% of their department’s total salary bill :-

SQL> SELECT E1.EMP_NAME FROM EMP E1


2 WHERE SALARY >
3 ( SELECT ( SUM( SALARY ) )*0.4
4 FROM EMP E2
5 WHERE E1.DEPT_NO = E2.DEPT_NO );

The employee’s salary is taken from table EMP, but so are the salaries which are used to
calculate 40% of the salary bills. It is therefore essential to distinguish between the two
references to EMP.

4
School of Computing, Engineering and Information Sciences
University of Northumbria

This is done by giving each of the two references to EMP its own special name or alias in
the FROM phrase; in the above example, the aliases are E1 and E2. Each alias can then
be treated as if it referred to an entirely separate and independent copy of the aliased
table; this includes prefixing column names in order to show which alias of the table the
column comes from.
Without these aliases, the above query could not be written in SQL.

Exercise: execute the above example query.

Note that aliases are a general-purpose facility in SQL. They can be used anywhere
where 2 or more references need to be made to the same table in the same statement.
They are not limited to being used in subqueries.

SUBQUERIES WITH MULTIPLE VALUE COMPARISONS


Example : get details of the projects worked on by employee E2 :-

SQL> SELECT * FROM PROJ


2 WHERE PROJ_NO IN
3 (SELECT PROJ_NO FROM ALLOC
4 WHERE EMP_NO = 'E2');

Exercise:
Execute the above query.
Write an equivalent query that does not use a subquery. Check you get the same result.

Get the details of the projects not worked on by employee E2.

Get the names of employees not allocated to projects.

Get the details of all employees who are not departmental managers.

Example : get the details of employees who are managers :-

SQL> SELECT * FROM EMP


2 WHERE EXISTS
3 (SELECT * FROM DEPT
4 WHERE MANAGER_NO = EMP_NO);

5
School of Computing, Engineering and Information Sciences
University of Northumbria

Exercise:
Execute the above query.
Write an equivalent query that does not use a subquery. Check you get the same result.

Do the obverse of the above query and get the details of employees who are not managers.

Get details of employees who are not allocated to any projects.

Example : get the details of employees whose salary is less than those of all married
employees :-

SQL> SELECT * FROM EMP


2 WHERE SALARY <ALL
3 ( SELECT SALARY FROM EMP
3 WHERE MARITAL_STATUS = 'M' );

ALL is used with a comparison θ (i.e. θ stands for =, <, > etc) and is true if the
comparison is valid for every row of the table produced by the subquery.
Exercise:
Execute the above query.
Write an equivalent query that uses a subquery in a different way. Check you get the same result.

Get the details of employees whose salary is less than that of all those employees who work on project P2.

Get details of the department with the largest budget; use >=ALL. Write an equivalent query that does not
use >=ALL. Check you get the same result.

Example : get the details of employees who manage a department :-

SQL> SELECT * FROM EMP


2 WHERE EMP_NO =ANY
3 ( SELECT MANAGER_NO FROM DEPT );

ANY is also used with =, <, > etc., and is true if the comparison is valid for one or more
of the rows of the subquery result table.

6
School of Computing, Engineering and Information Sciences
University of Northumbria

Exercise:
Execute the above query.
Write an equivalent query that uses a subquery in a different way. Check you get the same result.

Get the name of any employees whose salary is less than that of any manager.

Get the name of any employees whose salary is greater than that of any manager.

NESTED SUBQUERIES
Example : get details of all employees who work on the same project(s) that Fletcher
works on :-

SQL> SELECT * FROM EMP


2 WHERE EMP_NO IN
3 ( SELECT EMP_NO
4 FROM EMP NATURAL JOIN ALLOC
5 WHERE PROJ_NO =ANY
6 ( SELECT PROJ_NO
7 FROM EMP NATURAL JOIN ALLOC
8 WHERE EMP_NAME = 'Fletcher' ) ) ;

Exercise:
Execute the above query. Comment on the result returned.

Get the details of all employees who don’t work on any of the projects that Fletcher works on .

SUBQUERIES IN THE ‘FROM’ PHRASE


Example : for each group of employees by marital status, get their total salary bill,
excluding those employees whose marital status is currently unknown :-

7
School of Computing, Engineering and Information Sciences
University of Northumbria

SQL> SELECT *
2 FROM ( SELECT MARITAL_STATUS, SUM( SALARY ) AS SALARY_BILL
3 FROM EMP
4 GROUP BY MARITAL_STATUS )
SALARY_BILL_BY_MARITAL_STATUS
5 WHERE MARITAL_STATUS <> '?' ;

To give the table in the FROM phrase a name, we would expect to put ‘AS TableName’
after the subquery, in order to be consistent with the corresponding syntax in other parts
of SQL. In Oracle at least, inserting the keyword AS results in an error, so the
‘TableName’ must appear on its own after the subquery.

Exercise:
Execute the above query.

Use the same approach to get the project number(s) of those project(s) that have more than 2 employees
working on them .

SUBQUERIES IN THE ‘SELECT’ PHRASE


Example : for each employee whose salary exceeds £16,000, get their name and that of
the department they work in :-

SQL> SELECT EMP_NAME,


2 ( SELECT DEPT_NAME FROM DEPT
3 WHERE DEPT.DEPT_NO = EMP.DEPT_NO ) AS DEPT_NAME
5 FROM EMP
6 WHERE SALARY > 16000;

Note that :
the subquery is correlated,
the keyword AS can and should be used to name the subquery result !

Exercise:
Execute the above query.

Use the same approach to get for each employee of ‘single’ marital status, their name, salary, and potential
bonus (which is defined as 10% of their department’s budget).

You might also like