CS F212 Database Systems
Todays Class
Relational
SQL
Model
Find age of the youngest sailor with age
18, for each rating with at least 2 such
sailors
S.rating, MIN (S.age)
AS minage
FROM Sailors S
WHERE S.age >= 18
GROUP BY S.rating
HAVING COUNT (*) > 1
SELECT
Answer relation:
Sailors instance:
Find age of the youngest sailor with
age
18, for each rating with at least 2 such
sailors.
Nested Subqueries
SQL provides a mechanism for the nesting
of subqueries.
A subquery is a select-from-where
expression that is nested within another
query.
A common use of subqueries is to perform
tests for set membership, set
comparisons, and set cardinality.
What Is a Subquery?
A subquery is a SELECT statement
embedded in a clause of another SQL
statement.
Main
Query
SELECT . . .
FROM . . .
WHERE . . (SELECT
.
...
FROM . . .
WHERE . . .)
Subquery
Subqueries
SELECT
FROM
WHERE
select_list
table
expr operator (SELECT select_list
FROM table);
The subquery (inner query) executes
once before the main query.
The result of the subquery is used by the
main query (outer query).
Using a Subquery
SQL> SELECT ename
2 FROM
emp
2975
3 WHERE sal >
4
(SELECT sal
5
FROM
emp
6
WHERE empno = 7566);
ENAME
ENAME
------------------KING
KING
FORD
FORD
SCOTT
SCOTT
Correlated Subqueries
Used to affect row-by-row processing,
each subquery is executed once for
every row of the outer query.
GET
candidate row
EXECUTE
inner query using candidate row value
USE
value(s) from inner query to qualify
candidate row
Correlated Subqueries
SELECT outer1, outer2, ...
FROM
table1 alias1
WHERE outer1 operator
(SELECT inner1
FROM
table2 alias2
WHERE
alias1.outer2 =
alias2.inner1);
The subquery references a column from
a table in the parent query.
Using Correlated Subqueries
Find all employees who make more
than the average salary in their
department.
SQL>
SELECT empno, sal, deptno
Each time the outer query
2
3
4
5
FROM
WHERE
is processed the
emp outer
inner query is
sal > (SELECT AVG(sal)
evaluated.
FROM
emp inner
WHERE outer.deptno = inner.deptno);
EMPNO
SAL
DEPTNO
EMPNO
SAL
DEPTNO
--------------- ----------------- ----------------7839
5000
10
7839
5000
10
7698
2850
30
7698
2850
30
7566
2975
20
7566
2975
20
...
...
66 rows
rows selected.
selected.
In Construct
Find all customers who have both an
account and a loan at the bank.
select distinct customer_name
from borrower
where customer_name in (select customer_name
from depositor )
Find all customers who have a loan at
the bank but do not have an account at
the
bank customer_name
select
distinct
from borrower
where customer_name not in (select customer_name
from depositor )
Nested Queries
Find names of sailors whove reserved boat #103:
SELECT S.sname
FROM Sailors S
WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)
A very powerful feature of SQL: a WHERE clause can itself
contain an SQL query! (Actually, so can FROM and
HAVING clauses.)
To find sailors whove not reserved #103, use NOT IN.
To understand semantics of nested queries, think of a
nested loops evaluation: For each Sailors tuple, check the
qualification by computing the subquery.
Example Query
Find all customers who have both an account and a
loan at the Perryridge branch
select distinct customer_name
from borrower, loan
where borrower.loan_number = loan.loan_number
and
branch_name = 'Perryridge' and
(branch_name, customer_name ) in
(select branch_name, customer_name
from depositor, account
where depositor.account_number =
account.account_number )
Note: Above query can be written in a much simpler
manner. The
formulation above is simply to illustrate SQL
features.
Some Construct
Find all branches that have greater assets than
some branch located in Brooklyn.
select distinct T.branch_name
from branch as T, branch as S
where T.assets > S.assets and
S.branch_city = 'Brooklyn'
Same query using > some clause
select branch_name
from branch
where assets > some
(select assets
from branch
where branch_city = 'Brooklyn')
All Construct
Find the names of all branches that have greater
assets than all branches located in Brooklyn.
select branch_name
from branch
where assets > all
(select assets
from branch
where branch_city = 'Brooklyn')
Nested Queries with Correlation
Find names of sailors whove reserved boat #103:
SELECT S.sname
FROM Sailors S
WHERE EXISTS (SELECT *
FROM Reserves R
WHERE R.bid=103 AND
S.sid=R.sid)
EXISTS is another set comparison operator, like IN.
Exists Construct
Find all customers who have an account
at all branches located in Brooklyn.
select distinct S.customer_name
from depositor as S
where not exists (
(select branch_name
from branch
where branch_city = 'Brooklyn')
except
(select R.branch_name
from depositor as T, account as R
where T.account_number = R.account_number and
S.customer_name = T.customer_name ))
(1)
SELECT S.sname
FROM Sailors S
Division in SQL
WHERE NOT EXISTS
((SELECT B.bid
FROM Boats B)
ind sailors whove reserved all boats.
EXCEPT
Lets do it the hard way,
(SELECT R.bid
without EXCEPT:
FROM Reserves R
WHERE R.sid=S.sid
ELECT
(2) S.sname
ROM Sailors S
HERE NOT EXISTS (SELECT B.bid
FROM Boats B
Sailors S such that ... WHERE NOT EXISTS (SELECT R.bid
FROM Reserves R
WHERE R.bid=B.
there is no boat B without ...
AND R.sid=S
a Reserves tuple showing S reserved B
Absence of Duplicate Tuples
The unique construct tests whether a
subquery has any duplicate tuples in its
result.
Find all customers who have at most one
account at the Perryridge branch.
select T.customer_name
from depositor as T
where unique (
select R.customer_name
from account, depositor as R
where T.customer_name = R.customer_name and
R.account_number = account.account_number
and
account.branch_name = 'Perryridge')
Example Query
Find all customers who have at least two
accounts at the Perryridge branch.
select distinct T.customer_name
from depositor as T
where not unique (
select R.customer_name
from account, depositor as R
where T.customer_name = R.customer_name and
R.account_number = account.account_number
and
account.branch_name = 'Perryridge')
Variable from outer level is known as a
correlation variable
Derived Relations
o
o
SQL allows a subquery expression to be used in the from
clause
Find the average account balance of those branches
where the average account balance is greater than $1200.
select branch_name, avg_balance
from (select branch_name, avg (balance)
from account
group by branch_name )
as branch_avg ( branch_name, avg_balance )
where avg_balance > 1200
Note that we do not need to use the having clause, since
we compute the temporary (view) relation branch_avg in
the from clause, and the attributes of branch_avg can be
used directly in the where clause.
Find the maximum total balance across all
branches.
Select max(tot_balance)
From ( select branch_name, sum(balance)
from account
group by branch_name) as
branch_total(branch_name,tot_balance)
Null Values
It is possible for tuples to have a null value,
denoted by null, for some of their attributes
null signifies an unknown value or that a value
does not exist.
The predicate is null can be used to check for
null values.
Example: Find all loan number which appear
in the loan relation with null values for
amount.
select loan_number
from loan
where amount is null
The result of any arithmetic expression involving
null is null
Example: 5 + null returns null
Null Values and Three Valued Logic
Any comparison with null returns unknown
Example: 5 < null or null <> null
or
null = null
Three-valued logic using the truth value unknown:
OR: (unknown or true) = true,
(unknown or false) = unknown
(unknown or unknown) = unknown
AND: (true and unknown) = unknown,
(false and unknown) = false,
(unknown and unknown) = unknown
NOT: (not unknown) = unknown
P is unknown evaluates to true if predicate P
evaluates to unknown
Result of where clause predicate is treated as
false if it evaluates to unknown
Null Values and Aggregates
Total all loan amounts
select sum (amount )
from loan
Above statement ignores null amounts
All aggregate operations except
count(*) ignore tuples with null
values on the aggregated attributes.
Joined Relations
Join operations take two relations and return as a
result another relation.
These additional operations are typically used as
subquery expressions in the from clause
Join condition defines which tuples in the two
relations match, and what attributes are present in
the result of the join.
Join type defines how tuples in each relation
that do not match any tuple in the other relation
(based on the join condition) are treated.
Joined Relations Datasets for Examples
Relation loan
Relation borrower
Note: borrower information missing for
L-260 and loan information missing for
L-155
Joined Relations Examples
loan inner join borrower on
loan.loan_number = borrower.loan_number
loan left outer join borrower on
loan.loan_number =
borrower.loan_number
Joined
Relations
Examples
loan natural inner join borrower
loan natural right outer join borrower
stomers who have either an account or a loan (but not both)
select customer_name
from (depositor natural full outer join borrower )
where account_number is null or loan_number is null
Joined
Relations
Examples
Natural join can get into trouble if two relations have
an attribute with same name that should not affect
the join condition
e.g. an attribute such as remarks may be present in many
tables
Solution:
loan full outer join borrower using (loan_number)
View Definition
A relation that is not of the conceptual model
but is made visible to a user as a virtual
relation is called a view.
A view is defined using the create view
statement which has the form
create view v as < query expression >
where <query expression> is any legal SQL
expression. The view name is represented by v.
Once a view is defined, the view name can be
used to refer to the virtual relation that the
view generates.
Example
Queries
A view consisting of branches and their customers
create view all_customer as
(select branch_name, customer_name
from depositor, account
where depositor.account_number =
account.account_number )
union
(select branch_name, customer_name
from borrower, loan
where borrower.loan_number = loan.loan_number )
Find all customers of the Perryridge
select customer_name
branch
from all_customer
where branch_name = 'Perryridge'
Uses of Views
Hiding some information from some users
Consider a user who needs to know a customers name, loan
number and branch name, but has no need to see the loan
amount.
Define a view
(create view cust_loan_data as
select customer_name,borrower.loan_number,
branch_name
from borrower, loan
where borrower.loan_number = loan.loan_number )
Grant the user permission to read cust_loan_data, but not
borrower or loan
Predefined queries to make writing of other queries
easier
Common example: Aggregate queries used for statistical
analysis of data
Processing of Views
When a view is created
the query expression is stored in the database along with
the view name
the expression is substituted into any query using the view
Views definitions containing views
One view may be used in the expression defining another
view
A view relation v1 is said to depend directly on a view
relation v2 if v2 is used in the expression defining v1
A view relation v1 is said to depend on view relation v2 if
either v1 depends directly to v2 or there is a path of
dependencies from v1 to v2
A view relation v is said to be recursive if it depends on
itself.
View Expansion
A way to define the meaning of views defined in terms
of other views.
Let view v be defined by an expression e that may
itself contain uses of view relations.
View expansion of an expression repeats the following
replacement step:
repeat
Find any view relation v in e
Replace the view relation v by the expression defining
vi
until no more view relations are present in e
As long as the view definitions are not recursive, this
loop will terminate
With
Clause
The with clause provides a way of defining a
temporary view whose definition is available
only to the query in which the with clause
occurs.
Find all accounts with the maximum balance
with max_balance (value) as
select max (balance)
from account
select account_number
from account, max_balance
where account.balance =
max_balance.value
Complex Queries using With
Clause
Find all branches where the total account deposit is
greater than the average of the total account deposits at
all branches.
with branch_total (branch_name, value) as
select branch_name, sum (balance)
from account
group by branch_name
with branch_total_avg (value) as
select avg (value)
from branch_total
select branch_name
from branch_total, branch_total_avg
where branch_total.value >=
branch_total_avg.value
Note: the exact syntax supported by your database
may vary slightly.
E.g. Oracle syntax is of the form
with branch_total as ( select .. ),
branch_total_avg as ( select .. )
select