You are on page 1of 35

Lab 7: SQL-DML Tutorial

Use company schema came along this lab for this tutorial. Upload the SQL script to create and
populate database using APEX.
This document has many examples of each SQL construct to understand how each SQL
construct just for your learning. Use separate lab tasks to submit your week 6 assignment.

Table of Content

s
Lab 7 –Introduction to Basic SQL................................................................................................................2
Loading the Tables and Data...................................................................................................................2
Anatomy of a SQL Statement..................................................................................................................5
SELECT Statement with a Condition........................................................................................................5
Practice:..................................................................................................................................................8
For each of the task below, use APEX to create query. Copy a screenshot of query and its results using
APEX......................................................................................................................................................8
WHERE and ORDER BY.................................................................................................................................9
Syntax with Examples..............................................................................................................................9
Lab Task 2:.............................................................................................................................................11
GROUP Functions......................................................................................................................................12
SELECT Statement with Group Functions..............................................................................................12
SELECT Statement with Group By Clause...............................................................................................14
SELECT Statement with Group By and Having Clauses..........................................................................16
SELECT Statement with Set Operators...................................................................................................18
Fundamentals of Subqueries.....................................................................................................................19
Subquery Overview...............................................................................................................................19
Single Row Subquery.........................................................................................................................20
Multiple Row Subquery.....................................................................................................................22
Practice.....................................................................................................................................................25
Subqueries: use nested queries only.....................................................................................................25
Aggregate function................................................................................................................................25
Ordering of query results.......................................................................................................................26
Grouping function.................................................................................................................................26
Introduction to Joins.................................................................................................................................26
SELECT Statement with NATURAL JOIN.............................................................................................27
SELECT Statement with CROSS JOIN..................................................................................................29
SELECT Statement with JOIN and USING Clause................................................................................29
SELECT Statement with JOIN and ON Clause.........................................................................................30
SELECT Statement to Join 3 Tables....................................................................................................31
SELECT Statement with LEFT and RIGHT OUTER JOIN........................................................................31
SELECT Statement with FULL OUTER JOIN.........................................................................................32
SELECT Statement with SELF JOIN.....................................................................................................33
Practice.....................................................................................................................................................34

Lab 7 –Introduction to Basic SQL


Note: For this lab, you must upload and run the SQL script (company_Schema.sql) that came
along with the lab. Follow data upload steps as shown below:

Loading the Tables and Data


It is essential to have at least the tables defined in order for the Create Application wizard to
generate pages in your application. In this activity, you create the required database objects and
populate the tables with sample data.
1. Use SQL Workshop to upload a script that creates the tables for the Demo Projects
application. Perform the following steps:
1. Navigate to SQL Workshop and select SQL Scripts

2. Click Upload

3. Click Choose File

2
4. Navigate to the working directory where you extracted apex-course-labs.zip. Locate
the Project_Tables.sql file, and double-click the file or click the file and then click
Open. Click Upload.

3
5. Review the uploaded script to see what tables will be created. In the SQL Scripts list,
click the Edit icon (pencil), to the left of the script you just uploaded.

6. Click the Run icon to the right of the script you uploaded.

7. Then, click Run Now

4
Anatomy of a SQL Statement
SELECT <attribute list>
FROM <table list>
WHERE <condition>;
where

■ <attribute list> is a list of attribute names whose values are to be retrieved by the query.
■ <table list> is a list of the relation names required to process the query.
■ <condition> is a conditional (Boolean) expression that identifies the tuples to be retrieved by the
query.

SELECT Statement with a Condition

SELECT <column1>, … <columnN> FROM <table_name> WHERE <condition> ;

Example Explanation
Using Comparison Operators
SELECT DISTINCT country_id It displays unique country_id from table
FROM locations locations for all rows that have location_id
WHERE location_id<2000 less than 2000.

Note: To see the effect, repeat the statement without


the word DISTINCT.

SELECT employee_id, first_name, email, It displays 4 of 12 columns and all rows of


hire_date FROM employees table employees whose employee_id is less
WHERE employee_id<200; than 200.

5
Example Explanation

Reminder: Use DESC to know the structure of a table.

SELECT employee_id, first_name, hire_date It displays 3 of 12 columns and all rows of


FROM employees table employees who were hired before 1-
WHERE hire_date<TO_DATE('1-1-2000','dd- Jan-2000.
mm-yyyy');

Using Concatenation Operator


SELECT 'A city from the US is ' || city It displays a concatenation of literal value
FROM locations and column city for all rows in table
WHERE country_id='US'; locations whose country_id is ‘US’.

SELECT street_address||' ' ||city as It displays a concatenation of columns


full_address FROM locations street_address and city with alias
WHERE country_id='US'; full_address for all rows in table locations
with country_id of ‘US’.
SELECT department_id || ' '|| ||' '|| is used to make a space between the
department_name department_id and department_name
FROM departments; The 'space' character in single quotation
marks creates a space between the column
values
SELECT department_id ||' '|| Column aliases (e.g. Department Info) are
department_name AS " Department Info " useful when using the concatenation
FROM departments; operator so that the default SELECT line
does not appear as the column heading.
SELECT first_name ||' '||
last_name AS "Employee Name"
FROM employees;

Concatenation and Literal Values You can also include numbers as literal
values. In the following example, the
number 1 is concatenated to the strings, 'has
a 'and 'year salary of '

6
Example Explanation
SELECT last_name ||' has a '|| 1 ||' year salary
of '||
salary*12 || ' dollars.' AS Pay
FROM employees;

Using Between, In, and Like


SELECT employee_id, salary, salary*0.1 as It displays 2 of 12 existing columns plus 1
rate derived column called “rate” (alias) and all
FROM employees rows of table employees with salaries
WHERE salary BETWEEN 10000 AND between 10000 and 12000.
12000;
SELECT * It displays all columns and all rows from
FROM employees table employees with job_id either
WHERE job_id IN ('SA_MAN', 'SA_REP'); ‘SA_MAN’ or ‘SA_REP’ (Sales Manager or
Sales Representative)

SELECT * It displays all columns and all rows from


FROM employees table employees whose first_name starts
WHERE first_name LIKE 'J%'; with ‘J’.
The character ‘%’ represents none, one or
more characters.

SELECT * It displays all columns and all rows from


FROM employees table employees whose first_name starts
WHERE first_name LIKE '_e_'; with any character, 2nd character ‘e’, and
any 3rd character. The name should consist
of only 3 letters (e.g Lex).
The character ‘_’ represents one and only
one character.

SELECT * As the above example, the 1st character can


FROM employees be anything, the 2nd must be ‘e’ but the next
WHERE first_name LIKE '_e%'; characters can be none, one or more.

Using IS NULL
SELECT * It displays all columns and all rows of
FROM departments departments table whose manager_id is
WHERE manager_id is null; null (empty).

7
Practice:
For each of the task below, use APEX to create query. Copy a screenshot of query and its results
using APEX.

1. Create a SQL statement that displays only the first_name and salary of an employee
whose salary is greater than 10,000.

2. Create a SQL statement that displays only the first_name and salary of an employee
whose salary is between 10000 and 15000.

3. Create a SQL statement that displays the first_name and last_name of employees whose
last_name is ‘Smith’.

4. Create a SQL statement that displays the first_name and last_name of employees whose
last_name is either ‘Smith’, ‘King’, or ‘Rogers’.

5. Create a SQL statement that displays the first_name and last_name of employees whose
last_name starts with ’S’.

8
WHERE and ORDER BY
 create SELECT Statements using logical operators
 create SELECT Statements using ORDER BY
 create SELECT Statements using column aliases
 create SELECT Statements using sorting with other columns
 create SELECT Statements using sorting with multiple columns
Logical conditions combine the result of two or more conditions to produce a single result. In
SQL, the basic logical comparison operators for comparing attribute values with one another and
with literal constants are =, <, <=, >, >=, and, or, <>.
These correspond to the relational algebra operators =, <, ≤, >, ≥, and ≠, respectively, and to the
C/C++ programming language operators =, <, <=, >, >=, and !=. The main syntactic
difference is the not equal operator. SQL has additional comparison operators that we will
present gradually.

Syntax with Examples

SELECT <column1>, … <columnN> FROM <table_name> WHERE <condition>


ORDER BY <column> [DESC]

The order of execution is as follows:


 FROM clause: locate the table that contains data
 WHERE clause: restrict the rows to be returned
 SELECT clause: selects from the reduced data set columns requested
 ORDER BY clause: orders the result set

Example Explanation
Using Logical Operators
SELECT last_name, department_id, salary In the query shown, the results returned
FROM employees will be rows that satisfy BOTH
WHERE department_id > 50 AND salary > 12000; conditions specified in the WHERE
clause.

SELECT last_name, hire_date, job_id Another example of using AND in the


FROM employees where clause.
WHERE hire_date > '01/jan/1998' AND job_id
LIKE 'SA%';

SELECT department_name, manager_id, all rows returned have a location_id of


location_id 2500 OR they have a manager_id equal

9
Example Explanation
FROM departments to 124
WHERE location_id = 2500 OR manager_id=124;

SELECT department_name, location_id The NOT operator will return rows that
FROM departments do NOT satisfy the condition in the
WHERE location_id NOT IN (1700,1800); WHERE clause.

SELECT last_name||' '||salary*1.05 The precedence order of operators is


As "Employee Raise" Arithmetic, Concatenation, Comparison,
FROM employees IS NULL, LIKE, IN, BETWEEN, NOT,
WHERE department_id IN(50,80) AND, and the last is OR.
AND first_name LIKE 'C%'
OR last_name LIKE '%s%';

Using Order By
SELECT last_name, hire_date uses the ORDER BY clause to order
FROM employees hire_date in ascending (default) order
ORDER BY hire_date;

SELECT last_name, hire_date uses the ORDER BY clause to order


FROM employees hire_date in descending (DESC) order
ORDER BY hire_date DESC;
Using Column Aliases
SELECT last_name, hire_date as "Date Started" The alias used in the SELECT statement
FROM employees is referenced in the ORDER BY clause.
ORDER BY "Date Started";

Sorting with Other Columns


SELECT employee_id, first_name the data is sorted by the last_name
FROM employees column even though this column is not
WHERE employee_id < 105 listed in the SELECT statement
ORDER BY last_name; It is difficult to verify your results when
you sort by a column that you're not

10
Example Explanation
SELECTing. In the real world, you
would run your query selecting the
last_name column until you were sure
you were getting the right data. Then
you could remove that column from
your SELECT statement.

Sorting with Multiple Columns


SELECT department_id, last_name Employees are first ordered by
FROM employees department number (from lowest to
WHERE department_id <= 50 highest), then for each department, the
ORDER BY department_id, last_name; last names are displayed in alphabetical
order (A to Z).

SELECT department_id, last_name If you want to reverse the sort order of a


FROM employees column, add DESC after its name.
WHERE department_id <= 50
ORDER BY department_id DESC, last_name;

Lab Task 2:
Use the company database to perform the following operations. Use order by and column aliases
to make the results meaningful.
To perform this lab activity, you first need to upload companySchema.SQl by following the data
upload steps, you already learned.
1. Retrieve the name and address of all employees who work for the ‘Research’ department.
Sort results by the first name.
2. For every project located in ‘Stafford’, list the project number, the controlling department
number, and the department manager’s last name, address, and birth date.
3. For each employee, retrieve the employee’s first and last name and the first and last name of
his or her immediate supervisor.

11
GROUP Functions
In SQL, the following group functions can operate on a whole table or on a specific grouping of rows.
Each function returns one result.
Group Functions include AVG, COUNT, MIN, MAX, SUM, VARIANCE, and STDDEV.

SELECT Statement with Group Functions

Example Output
Using MIN
SELECT MIN(life_expect_at_birth) 32.62
AS "Lowest Life Exp"
FROM wf_countries;

SELECT MIN(country_name) Anguilla


FROM wf_countries;

SELECT MIN(hire_date) 17/Jun/1987


FROM employees;

Using MAX
SELECT MAX(life_expect_at_birth) 83.51
AS "Highest Life Exp"
FROM wf_countries;

SELECT MAX(country_name) Western Sahara


FROM wf_countries

SELECT MAX(hire_date) 29/Jan/2000


FROM employees;

Using SUM
SELECT SUM(area) 241424
FROM wf_countries
WHERE region_id = 29;

SELECT SUM(salary) 58000


FROM employees
WHERE department_id = 90;

Using AVG

12
Example Output
SELECT AVG(area) 9656.96
FROM wf_countries
WHERE region_id = 29;

SELECT ROUND(AVG(salary), 2) 19333.33


FROM employees
WHERE department_id = 90;

Using VARIANCE
SELECT 143.2394
ROUND(VARIANCE(life_expect_at_birth),4)
FROM wf_countries;
Using STDDEV
SELECT ROUND(STDDEV(life_expect_at_birth), 11.9683
4)
FROM wf_countries;

Using Several Group Functions


SELECT MAX(salary), MIN(salary), 9000 4200 103
MIN(employee_id) FROM employees WHERE
department_id = 60;

Using COUNT
SELECT COUNT(job_id) FROM employees; 20

SELECT COUNT(commission_pct) FROM 4


employees;

Using COUNT All Rows


SELECT COUNT(*) 9
FROM employees
WHERE hire_date < '01/Jan/1996';

Using DISTINCT and COUNT


SELECT COUNT (DISTINCT job_id) 12
FROM employees;

SELECT COUNT (DISTINCT salary) 18


FROM employees;

Using NVL

13
Example Output
SELECT AVG(commission_pct) FROM .2125
employees;

SELECT AVG(NVL(commission_pct, 0)) .0425


FROM employees;

SELECT Statement with Group By Clause

SELECT <column1>, … <columnN> FROM <table_name> WHERE <condition>


GROUP BY <column1>;

 You use the GROUP BY clause to divide the rows in a table into smaller groups.
 You can then use the group functions to return summary information for each group.
 Group functions require that any column listed in the SELECT clause that is not part of a
group function must be listed in a GROUP BY clause.
 If you include a group function (AVG, SUM, COUNT, MAX, MIN, STDDEV,
VARIANCE) in a SELECT clause along with any other individual columns, each
individual column must also appear in the GROUP BY clause.
 You cannot use a column alias in the GROUP BY clause.
 The WHERE clause excludes rows before they are divided into groups.

Example Explanation
SELECT department_id, The rows are being grouped by department_id. The AVG
AVG(salary) function is then applied to each group.
FROM employees
GROUP BY department_id
ORDER BY department_id;

SELECT MAX(salary) FROM To find the maximum salary of employees in each


employees GROUP BY department
department_id;

14
Example Explanation
Column department_id is added to tell which maximum
salary belongs to which department

But how can we tell which maximum salary belongs to


which department?
Usually we want to include the
GROUP BY column in the
SELECT list

SELECT department_id,
MAX(salary)
FROM employees
GROUP BY department_id;

SELECT COUNT(country_name), This example shows how many countries are in each
region_id FROM wf_countries region.
GROUP BY region_id ORDER Remember that group functions ignore null values, so if
BY region_id; any country does not have a country name, it will not be
included in the COUNT.

SELECT COUNT(*), region_id Unlike the previous example, this one will count all of
FROM wf_countries GROUP BY the rows in each region group, without the need to check
region_id ORDER BY region_id; which columns contained NULL values.

15
Example Explanation
SELECT department_id, WHERE Clause: We can also use a WHERE clause to
MAX(salary) exclude rows before the remaining rows are formed into
FROM employees groups
WHERE last_name != 'King'
GROUP BY department_id;

As employee King is excluded by the WHERE clause,


the MAX(salary) for department 90 is returned as 17000.

SELECT region_id, Shows the average population of all countries in each


ROUND(AVG(population)) AS region.
population Rounds the average to a whole number
FROM wf_countries
GROUP BY region_id
ORDER BY region_id;
SELECT country_id, Counts the number of spoken languages for all countries.
COUNT(language_id) AS
"Number of languages"
FROM wf_spoken_languages
GROUP BY country_id;
SELECT department_id, job_id, This example shows how many employees are doing each
count(*) job within each department.
FROM employees
WHERE department_id > 40
GROUP BY department_id,
job_id;
SELECT max(avg(salary)) Group functions can be nested to a depth of two when
FROM employees GROUP BY is used.
GROUP by department_id;

SELECT Statement with Group By and Having Clauses

SELECT <column1>, … <columnN> FROM <table_name> WHERE <condition>


GROUP BY <column1> HAVING <condition>;

16
.

Example Explanation
Suppose we want to find the maximum salary in A WHERE clause can be used only to
each department, but only for those departments include/exclude individual rows, not
which have more than one employee? groups of rows. Therefore we cannot
What is wrong with this example? use group functions in a WHERE
SELECT department_id, MAX(salary) clause.
FROM employees In the same way, you used the WHERE
WHERE COUNT(*) > 1 clause to restrict the rows that you
GROUP BY department_id; selected, you can use the HAVING
clause to restrict groups.
In a query using a GROUP BY and
HAVING clause, the rows are first
grouped, group functions are applied,
and then only those groups matching the
HAVING clause are displayed.

SELECT department_id,MAX(salary) The WHERE clause is used to restrict


FROM employees rows; the HAVING clause is used to
GROUP BY department_id restrict groups returned from a GROUP
HAVING COUNT(*)>1 BY clause.
ORDER BY department_id; The query first finds the MAX salary for
each department in the employees table.
The HAVING clause then restricts the
groups returned to those departments
that have more than 1 employee.

The HAVING and GROUP BY clauses can use This query finds the average population
different columns. The example on GROUPs BY of the countries in each region.
region_id, but the HAVING clause restricts groups It then only returns the region groups
based on population. with a lowest population greater than
SELECT region_id, three hundred thousand.
ROUND(AVG(population)) You place each clause in the following
FROM wf_countries order:
GROUP BY region_id SELECT column, group_function
HAVING MIN(population)>300000 FROM table
ORDER BY region_id; WHERE
GROUP BY
HAVING

17
Example Explanation
Suppose we want to find the maximum salary in A WHERE clause can be used only to
each department, but only for those departments include/exclude individual rows, not
which have more than one employee? groups of rows. Therefore we cannot
What is wrong with this example? use group functions in a WHERE
SELECT department_id, MAX(salary) clause.
FROM employees In the same way, you used the WHERE
WHERE COUNT(*) > 1 clause to restrict the rows that you
GROUP BY department_id; selected, you can use the HAVING
clause to restrict groups.
In a query using a GROUP BY and
HAVING clause, the rows are first
grouped, group functions are applied,
and then only those groups matching the
HAVING clause are displayed.

ORDER BY

SELECT Statement with Set Operators


 Set operators are used to combine the results from different SELECT statements into one
single result output
 Sometimes you want a single output from more than one table
 If you join the tables, the rows that meet the join criteria are returned, but what if a join
will return a result set that doesn't meet your needs?
 This is where SET operators come in
 They can return the rows found in multiple SELECT statements, the rows that are in one
table and not the other, or the rows common to both statements
 There are a few rules to remember when using SET operators:
 The number of columns and the data types of the columns must be identical in all of
the SELECT statements used in the query.
 The names of the columns need not be identical.
 Column names in the output are taken from the column names in the first SELECT
statement.
 So any column aliases should be entered in the first statement as you would want to
see them in the finished report.
 The clauses we will use are UNION, UNION ALL, INTERSECT, and MINUS.

18
Example Explanation
SELECT hire_date, employee_id, job_id
FROM employees
UNION
SELECT TO_DATE(NULL),employee_id,
job_id
FROM job_history;

The employees table contains a hire date, employee


id and a job id.
The job history table contains employee id and job
id, but does not have a hire date column.
The two tables have the employee id and job id in
common, but job history does not have a hire_date.
You can use the TO_CHAR(NULL) function match
columns in a SELECT list.
One NULL is included for each missing column.
Furthermore, NULL is formatted to match the data
type of the column it is standing in for, so
TO_CHAR, TO_DATE, or TO_NUMBER
functions are used to achieve identical SELECT
lists. The rows with NULL values for
hire_date are from the job_history table
SELECT hire_date, employee_id, job_id Using the previous query example, we
FROM employees could ORDER BY employee_id to see
UNION the jobs each employee has held
SELECT TO_DATE(NULL),employee_id, job_id
FROM job_history
ORDER BY employee_id;

Exercise: Modify the above queries by replacing


union with other set operators such as MINUS,
INTERSECT, and UNION ALL and analyse the
result set to observe the difference

Fundamentals of Subqueries
 Throughout this course, you have written queries to extract data from a database
 What if you wanted to write a query, only to find out you didn't have all the information you
needed to construct it?
 You can solve this problem by nesting queries—placing one query inside the other query
 The inner query is called a "subquery."

19
Subquery Overview
 A subquery is a SELECT statement that is embedded in a clause of another SELECT
statement
 A subquery executes once before the main query
 The result of the subquery is used by the main or outer query
 Subqueries can be placed in a number of SQL clauses, including the WHERE clause, the
HAVING clause, and the FROM clause
 The subquery syntax is:

SELECT select_list
FROM table
WHERE expression operator
(SELECT select_list The SELECT statement in parentheses is the
FROM table);
inner query or 'subquery'. It executes first,
before the outer query

 The two types of subqueries are:


o Single-row subqueries that use single-row operators (>, =, >=, <>, <=) and return only one
row from the inner query
o Multiple-row subqueries that use multiple-row operators (IN, ANY, ALL) and return more
than one row from the inner query

Example Explanation
SELECT first_name, last_name, hire_date What if you wanted to find out the
FROM employees names of the employees that were hired
WHERE hire_date > after Peter Vargas?
(SELECT hire_date The first thing you need to know is the
FROM employees answer to the question, "When was Peter
WHERE last_name = 'Vargas'); Vargas hired?"
Once you know his hire date, then you
can select those employees whose hire
dates are after his.

SELECT last_name FROM employees WHERE If a subquery returns a null value or no


department_id = (SELECT department_id FROM rows, the outer query takes the results of
employees WHERE last_name = 'Grant'); the subquery (null) and uses this result
in its WHERE clause.
The outer query will then return no
rows, because comparing any value with
a null always yields a null.

20
Single Row Subquery
 They return only one row
 They use single-row comparison operators (=, >,>=, <, <=, <>)
 Always enclose the subquery in parentheses.
 Always place the subquery on the right hand side of the comparison condition.
 The outer and inner queries can get data from different tables.
 Only one ORDER BY clause can be used for a SELECT statement, and if specified, it
must be the last clause in the main SELECT statement.
 The only limit on the number of subqueries is the buffer size that the query uses.

Example Explanation
SELECT last_name, job_id, department_id The outer and inner queries can get data from
FROM employees different tables.
WHERE department_id = The subquery finds the department_id for
(SELECT department_id 'Marketing', the outer query uses the returned
FROM departments department_id to display rows from the
WHERE department_name = 'Marketing') employees table.
ORDER BY job_id;

SELECT last_name, job_id, salary, More than one subquery can return information
department_id to the outer query.
FROM employees The first subquery returns the job_id of
WHERE job_id = employee 141 (ST_CLERK). The second
(SELECT job_id subquery uses the departments table to find the
FROM employees department_id at location_id 1500 (50). The
WHERE employee_id = 141) outer query then returns rows from the
AND department_id = employees table that match both these values.
(SELECT department_id
FROM departments

21
Example Explanation
WHERE location_id = 1500);

"Which employees earn less than the Group function (AVG) in subquery. The
average salary?" subquery first finds the average salary for all
SELECT last_name, salary employees, the outer query then returns
FROM employees employees with a salary of less than the average.
WHERE salary <
(SELECT AVG(salary)
FROM employees);
Which departments have a lowest salary In this example, the subquery selects and returns
that is greater than the lowest salary in the lowest salary in department 50. The outer
department 50? query uses this value to select the department ID
SELECT department_id, MIN(salary) and lowest salaries of all the departments whose
FROM employees lowest salary is greater than that number. The
GROUP BY department_id HAVING clause eliminated those departments
HAVING MIN(salary) > whose MIN salary was less than department 50's
(SELECT MIN(salary) MIN salary.
FROM employees
WHERE department_id = 50);

Multiple Row Subquery


 Subqueries that return more than one value are called multiple-row subqueries.
 Because we cannot use the single-row comparison operators (=, <, and so on), we need
different comparison operators for multiple-row subqueries.
 The multiple-row operators are: IN, ANY, and ALL
 The NOT operator can be used with any of these three operators.

Example Explanation
Query Comparison
Whose salary is equal to the salary of an This example returns an error because
employee in department 20 ? more than one employee exists in
department 20, the subquery returns
SELECT first_name, last_name multiple rows
FROM employees

22
Example Explanation
WHERE salary =
(SELECT salary
FROM employees
WHERE department_id = 20);

We call this a multiple-row subquery


The problem is the equal sign (=) in the
WHERE clause of the outer query
How can one value be equal to (or not
equal to) more than one value at a time?
The IN operator is used within the outer query The inner query will return a list of the
WHERE clause to select only those rows which years that employees in department 90
are IN the list of values returned from the inner were hired.
query. For example, we are interested in all the The outer query will then return any
employees that were hired the same year as an employee that was hired the same year as
employee in department 90 any year in the inner query list.

SELECT last_name, hire_date


FROM employees
WHERE EXTRACT(YEAR FROM hire_date)
IN
(SELECT EXTRACT(YEAR FROM hire_date)
FROM employees
WHERE department_id=90);
EXTRACT function can be used to extract
YEAR, MONTH or DAY fields from a DATE
data type
The ANY operator is used when we want the The example shown will return any
outer-query WHERE clause to select the rows employee whose year hired is less than at
which match the criteria (<, >, =, etc.) of at least least one year hired of employees in
one value in the subquery result set. department 90

SELECT last_name, hire_date


FROM employees
WHERE EXTRACT(YEAR FROM hire_date) <
ANY
(SELECT EXTRACT(YEAR FROM hire_date)
FROM employees
WHERE department_id=90);
The ALL operator is used when we want the The ALL operator compares a value to
outer-query WHERE clause to select the rows every value returned by the inner query.

23
Example Explanation
which match the criteria ( <, >, =, etc.) of all of As no employee was hired before 1987, no
the values in the subquery result set. rows are returned.

SELECT last_name, hire_date FROM employees =ALL: How can one value equal every
WHERE EXTRACT(YEAR FROM hire_date) < one of a set of values? For this reason,
ALL =ALL is rarely used.
(SELECT EXTRACT(YEAR FROM hire_date)
FROM employees
WHERE department_id=90);
Dealing with Null Values
Suppose that one of the values returned by
SELECT last_name, a multiple-row subquery is null, but other
employee_id values are not.
FROM employees If IN or ANY are used, the outer query
WHERE employee_id IN will return rows which match the non-null
(SELECT manager_id values.
FROM employees);
If ALL is used, the outer query returns no
SELECT last_name, employee_id rows because ALL compares the outer
FROM employees query row with every value returned by
WHERE employee_id <= ALL the subquery, including the null.
(SELECT manager_id And comparing anything with null results
FROM employees); in null.

GROUP BY and HAVING


GROUP BY clause and the HAVING clause can also be used with multiple-row subqueries.
What if you wanted to find the departments
whose minimum salary is less than the salary of
any employee who works in department 10 or 20?
We need a multiple-row subquery which returns
the salaries of employees in departments 10 and
20. The outer query will use a group function
(MIN) so we need to GROUP the outer query BY
department_id.

SELECT department_id, MIN(salary)


FROM employees
GROUP BY department_id
HAVING MIN(salary) < ANY
(SELECT salary
FROM employees
WHERE department_id IN (10,20))
ORDER BY department_id;

24
Example Explanation

Multiple-Column Subqueries
Subqueries can use one or more columns.
If they use more than one column, they are called multiple-column subqueries.
A multiple-column subquery can be either pair-wise comparisons or non-pair-wise
comparisons.

The example below shows a multiple-column The query lists the employees whose
pair-wise subquery manager and departments are the same as
the manager and department of employees
SELECT employee_id, manager_id, 149 or 174.
department_id First, the subquery to retrieve the
FROM employees MANAGER_ID and DEPARTMENT_ID
WHERE(manager_id,department_id) IN values for the employees with
(SELECT manager_id,department_id EMPLOYEE_ID 149 or 174 is executed.
FROM employees These values are compared with the
WHERE employee_id IN (149,174)) MANAGER_ID column and the
AND employee_id NOT IN (149,174); DEPARTMENT_ID column of each row
in the EMPLOYEES table. If the values
match, the row is displayed. In the output,
the records of the employees with the
EMPLOYEE_ID 149 or 174 will not be
displayed.

SELECT employee_id, A non-pair-wise multiple-column


manager_id, subquery also uses more than one column
department_id in the subquery, but it compares them one
FROM employees at a time, so the comparisons take place in
WHERE manager_id IN different subqueries:
(SELECT manager_id First, the subquery to retrieve the
FROM employees MANAGER_ID values for the employees
WHERE employee_id IN (149,174)) with the EMPLOYEE_ID 149 or 174 is
AND department_id IN executed. Similarly, the second subquery
(SELECT department_id to retrieve the DEPARTMENT_ID values
FROM employees for the employees with the
25
Example Explanation
WHERE employee_id IN (149,174)) EMPLOYEE_ID 149 or 174 is executed.
AND employee_id NOT IN(149,174); The retrieved values are compared with
the MANAGER_ID and
DEPARTMENT_ID column for each row
in the EMPLOYEES table.

SELECT last_name AS "Not a Manager" In this example, the subquery is selecting


FROM employees emp the employees that are managers.
WHERE NOT EXISTS The outer query then returns the rows from
(SELECT * the employee table that do NOT EXIST in
FROM employees mgr the subquery.
WHERE mgr.manager_id = emp.employee_id);

Practice
Apply the SQL concepts learn in this lab on the company database for performing the following retrieval
operations.

Subqueries: use nested queries only


1. Returns the names of employees whose salary is greater than the salary of all the employees in
department 5
2. Retrieve the name of each employee who has a dependent with the same first name and is the
same sex as the employee.

Aggregate function
1. Find the sum of the salaries of all employees, the maximum salary, the minimum salary, and the
average salary.
2. Find the sum of the salaries of all employees of the ‘Research’ department, as well as the
maximum salary, the minimum salary, and the average salary in this department.
3. Retrieve the total number of employees in the company (Q1) and the number of employees in
the ‘Research’ department (Q2)
4. Count the number of distinct salary values in the database.

Ordering of query results


1. Retrieve a list of employees and the projects they are working on, ordered by department and,
within each department, ordered alphabetically by last name, then first name.
2. For each project, retrieve the project number, the project name, and the number of employees
from department 5 who work on the project.

26
Grouping function
1. For each department, retrieve the department number, the number of employees in the
department, and their average salary.
2. For each project, retrieve the project number, the project name, and the number of employees
who work on that project.
3. For each project on which more than two employees work, retrieve the project number, the
project name, and the number of employees who work on the project.
4. For each department that has more than five employees, retrieve the department number and
the number of its employees who are making more than $40,000.

Introduction to Joins
Up to now, your experience using SQL has been limited to querying and returning information
from one database table at a time
This would not be a problem if all data in the database were stored in only one table
But you know from data modeling that separating data into individual tables and being able to
associate the tables with one another is the heart of relational database design
Fortunately, SQL provides join conditions that enable information to be queried from separate
tables and combined in one report

27
A SQL join clause combines fields from 2 (or more) tables in a relational database as shown in
the below figure. The top table is combining departments and employee DEPT_ID as common
attribute in both table.

SELECT Statement with NATURAL JOIN


A natural join is based on all columns in two tables that have the same name and selects
rows from the two tables that have equal values in all matched columns.
In the tables below the employees table has a job_id column. This is a reference to the
column of the same name in the jobs table.

28
As shown in the sample code below, when using a natural join, it is possible to join the
tables without having to explicitly specify the columns in the corresponding table. However, the
names and data types of both columns must be the same

Example Explanation
SELECT first_name, last_name, job_id, job_title This join will return columns from the
FROM employees NATURAL JOIN jobs employees table and their related
WHERE department_id > 80; job_title from the jobs table based on
the common column job_id.
The WHERE clause was added to apply
an additional restriction to one of the
tables, to limit the rows of output. The
output is shown below

Here is another example: The departments and locations table


SELECT department_name, city both have a column, location_id, which
FROM departments NATURAL JOIN locations; is used to join the two tables. Notice
that the natural join column does not

29
Example Explanation
have to appear in the SELECT clause.

SELECT Statement with CROSS JOIN


CROSS JOIN joins each row in one table to every row in the other table. The result set
represents all possible row combinations from the two tables. If you CROSS JOIN a table with
20 rows with a table with 100 rows, the query will return 2000 rows.
The result set of a CROSS JOIN brings together data from two tables that are not logically
related to each other. CROSS JOINS are useful during testing to create large datasets to measure
database performance.

Example Explanation
SELECT last_name, department_name The employees table contains 20 rows
FROM employees CROSS JOIN departments; and the departments table has 8 rows.
Performing a CROSS JOIN will return
160 rows.

SELECT Statement with JOIN and USING Clause


In a natural join, if the tables have columns with the same names but different data types,
the join causes an error.
To avoid this situation, the join clause can be modified with a USING clause. The
USING clause specifies the columns that should be used for the join.
A USING clause is often preferred to a natural join even when the columns have the
same data type as well as the same name, because it clearly states exactly which join column is
being used.

Example Explanation
SELECT first_name, last_name, department_id, The columns referenced in the USING
department_name FROM employees JOIN clause should not have a qualifier (table
departments USING (department_id); name or alias) anywhere in the SQL
statement.
If the column in the USING clause has a
qualifier, the following error is returned
ORA-25154: column part of USING
clause cannot have qualifier.

SELECT first_name, last_name, department_id, The USING clause allows us to use


department_name WHERE to restrict rows from one or
FROM employees JOIN departments USING both tables.
(department_id)

30
Example Explanation
WHERE last_name = 'Higgins';

SELECT Statement with JOIN and ON Clause


What if the columns to be joined have different names, or if the join uses non-equality
comparison operators such as <, >, or BETWEEN ?
We can't use USING, so instead we use an ON clause. This allows a greater variety of
join conditions to be specified. The ON clause also allows us to use WHERE to restrict rows
from one or both tables.

Example Explanation
SELECT last_name, job_title In this example, the ON clause is used to
FROM employees e JOIN jobs j join the employees table with the jobs
ON (e.job_id = j.job_id); table.
A join ON clause is required when the
The example above uses table aliases as a qualifier common columns have different names
e.job_id = j.job_id, but could also have been written in the two tables
using the table names (employees.job_id =
jobs.job_id

When using an ON clause on columns with the


same name in both tables, you need to add a
qualifier (either the table name or alias) otherwise
an error will be returned

SELECT last_name, job_title The same query with a WHERE clause


FROM employees e JOIN jobs j to restrict the rows selected.
ON (e.job_id = j.job_id)
WHERE last_name LIKE 'H%'; Note: As the job_id column in the
employees and jobs tables have the same
name and data type, this query could
also be written with a NATURAL JOIN,
or a JOIN USING

Sometimes you may need to retrieve data from a table that has no corresponding column in
another table
Suppose we want to know the grade_level for each employees salary

31
Example Explanation
The job_grades table (shown below) does not have a common column with the employees
table . Using an ON clause allows us to join the two tables

SELECT last_name, salary, grade_level, This is to know the grade_level for each
lowest_sal, highest_sal employees salary. Even if the
FROM employees JOIN job_grades job_grades table does not have a
ON(salary BETWEEN lowest_sal AND common column with the employees
highest_sal); table.

SELECT Statement to Join 3 Tables


Suppose we need a report of our employees, their department, and the city where the
department is located?
We need to join three tables: employees, departments and locations
Both USING and ON can be used to join three or more tables

Example Explanation
SELECT last_name, department_name AS To produce a report of employees, their
"Department", city department, and the city where the
FROM employees JOIN departments USING department is located, we need to join
(department_id) three tables: employees, departments
JOIN locations USING (location_id); and locations.

SELECT Statement with LEFT and RIGHT OUTER JOIN


A join of two or more tables that returns only the matched rows is called an inner join.
All the join discussed are called inner join. When a join returns the unmatched rows as well as
the matched rows, it is called an outer join.

32
Example Explanation
SELECT e.last_name, d.department_id, note that the table name listed to the left of
d.department_name the words "left outer join" is referred to as
FROM employees e the "left table."
LEFT OUTER JOIN departments d ON This query will return all employee last
(e.department_id = d.department_id); names, both those that are assigned to a
department and those that are not

SELECT e.last_name, d.department_id, This right outer join would return all
d.department_name department IDs and department names, both
FROM employees e those that have employees assigned to them
RIGHT OUTER JOIN departments d ON and those that do not.
(e.department_id = d.department_id);

SELECT Statement with FULL OUTER JOIN


It is possible to create a join condition to retrieve all matching rows and all unmatched
rows from both tables. Using a full outer join solves this problem. The result set of a full outer
join includes all rows from a left outer join and all rows from a right outer join combined
together without duplication.

33
Example Explanation
SELECT e.last_name, d.department_id, Employees and departments tables are
d.department_name fully joined on their department_id using
FROM employees e FULL OUTER JOIN.
FULL OUTER JOIN departments d ON
(e.department_id = d.department_id);

SELECT Statement with SELF JOIN


In data modeling, it was sometimes necessary to show an entity with a relationship to
itself
For example, an employee can also be a manager.
We showed this using the recursive or "pig's ear" relationship

A self-join is use to join a table to itself as if it was two tables

Example Explanation
SELECT worker.last_name, “Manager name” is alias names that relate to
worker.manager_id, manager.last_name the data's association with that table.
AS "Manager name" Manager_id in the worker table is equal to
FROM employees worker JOIN employees employee_id in the manager table.
manager
ON (worker.manager_id =
manager.employee_id);

34
Example Explanation
To join a table to itself, the table is given two
names or aliases. This will make the database
"think" that there are two tables shown below

Practice
Apply the concepts learn in this lab on company database for retrieving following information.
1. Retrieve the name and address of all employees who work for the ‘Research’ department
without using join
2. Modify query 1 and observe results by using join
3. Modify query 1 and use subquery instead of join
4. Retrieve the last name of employees and their supervisors (natural join)
5. Modify query 4 to display all employees with supervisor and also that employee where a
supervisor is not assigned (left outer join)
6. Modify query 4 to display all the supervisors with and without employees assigned to
them (Right outer join)
7. Modify query 4 to display all employees with and without supervisors and all supervisors
with and without employees (Full outer join)

35

You might also like