Transcript Slide 1
Multiple Table Queries Part 4
Before starting to write your query
what are some good questions to ask
yourself?
- Which tables contain the
information I need?
- How are the tables related
to one another?
2
Student_Names
Student_Phones
Return phone type and number for all of
Will Ferrell’s phones
Student_Names
select
home.phone_type,
home.phone_number,
busn.phone_type,
busn.phone_number,
cell.phone_type,
cell.phone_number
Student_Phones
from
student_names sn
join
student_phones home on
home.student_id = sn.student_id and
home.phone_type = 'home'
join
student_phones cell on
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
join
student_phones busn on
busn.student_id = sn.student_id and
busn.phone_type = 'busn'
where
Results
sn.first_name = 'Will' and
sn.last_name = 'Ferrell'
Return phone type and number for all of
Will Ferrell’s phones
Student_Names
select
home.phone_number as "Home Phone",
busn.phone_number as "Business Phone",
cell.phone_number as "Cell Phone"
from
student_names sn
Student_Phones
join
student_phones home on
home.student_id = sn.student_id and
home.phone_type = 'home'
join
student_phones cell on
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
join
student_phones busn on
busn.student_id = sn.student_id and
busn.phone_type = 'busn'
where
sn.first_name = 'Will' and
sn.last_name = 'Ferrell’
Results
Return student names and all their
phones
Student_Names
select
sn.first_name,
sn.last_name,
home.phone_number as "Home Phone",
busn.phone_number as "Business Phone",
cell.phone_number as "Cell Phone"
from
Student_Phones
student_names sn
join
student_phones home on
home.student_id = sn.student_id and
home.phone_type = 'home'
join
student_phones cell on
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
join
student_phones busn on
busn.student_id = sn.student_id and
busn.phone_type = 'busn'
Results
Need to use outer joins
Return student names and all their
phones
Student_Names
select
sn.first_name,
sn.last_name,
home.phone_number as "Home Phone",
busn.phone_number as "Business Phone",
cell.phone_number as "Cell Phone"
from
Student_Phones
student_names sn
left outer join
student_phones home on
home.student_id = sn.student_id and
home.phone_type = 'home'
left outer join
student_phones cell on
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
left outer join
Results
student_phones busn on
busn.student_id = sn.student_id and
busn.phone_type = 'busn'
Return names of students who have cell
phones
Student_Names
select
sn.first_name,
sn.last_name
from
student_names sn
where
exists
(
select
Student_Phones
*
from
student_phones cell
where
cell.phone_type = 'cell'
)
Results
Given the data we have the
subquery will always return
something, so the existence
check will always prove true.
Need a correlated subquery.
Return names of students who have cell
phones
Student_Names
select
sn.first_name,
sn.last_name
from
student_names sn
where
exists
(
select
Student_Phones
*
from
student_phones cell
where
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
)
Results
Return names of students who have cell
phones
Student_Names
select
sn.first_name,
sn.last_name
from
student_names sn
where
exists
(
select
Student_Phones
*
from
student_phones cell
where
cell.student_id = sn.student_id and
cell.phone_type = 'cell'
)
Results
Now with the correlated
subquery we get back only
those students with a cell
phone
What does T-SQL stand for?
• Transact Structured Query Language
• Microsoft SQL Server
What does PL/SQL stand for?
• Procedural Language/Structured Query
Language
• Oracle
In Class Lab
Using 3 different approaches write 3 different queries that will
each answer the following data request:
List the boat names for all boats that do not
have any service requests
• Approach 1: utilize the "IN" operator
hint: subquery
• Approach 2: utilize the "exists" operator
hint: correlated subquery
• Approach 3: utilize an outer join
hint: if a match is not found null is returned
Approach 1: utilize the "IN" operator
hint: subquery
select
boat_name
from
a_marina_slip
where
slip_id not in
(
select
slip_id
from
a_service_request
)
Approach 2: utilize the "exists"
operator
hint: correlated subquery
select
boat_name
from
a_marina_slip m
where
not exists
(
select
*
from
a_service_request s
where
s.slip_id = m.slip_id
)
Approach 3: utilize an outer join
hint: if a match is not found null is
returned
select
boat_name
from
a_marina_slip m
left outer join
a_service_request s on
s.slip_id = m.slip_id
where
s.service_id is null
A working query performing the joins in the “where” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m,
a_owner o,
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Let’s change it to perform the joins in the “From” clause!
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m,
a_owner o,
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Essentially we’re going to
take the join conditions
from the “where” clause
and move them
into the “from”
clause
This is still the original query from the first slide; I simply added
some space between the tables for us to work in
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m,
a_owner o,
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
We no longer need the commas delimiting the tables
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m,
Get rid of commas
a_owner o,
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Add the word “join” between each set of tables
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o
join
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Add the word “on” after each table name that is preceded by a
“join”
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o
join
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Add the word “on” after each table name that is preceded by a
“join”
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o on
Note: the word “on” does
not go after the first table
in your query. It goes
after the tables that are
preceded by a “join”
join
a_marina_slip s on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
There isn’t a join we can perform directly that makes sense between
a_marina and a_owner because those two tables are not directly
related
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o on
join
a_marina_slip s on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Note: when joining in the “from” clause you can only join a
table to another table(s) that has been stated earlier in the
query
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o on
join
a_marina_slip s on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
a_marina and a_marina_slip are directly related so we can perform
a join between them. Lets switch a_marina_slip and a_owner
around
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o on
join
a_marina_slip s on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
a_marina and a_marina_slip are directly related so we can perform
a join between them. Lets switch a_marina_slip and a_owner
around
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_owner o on
join
a_marina_slip s on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
a_marina and a_marina_slip are directly related so we can perform
a join between them. Lets switch a_marina_slip and a_owner
around
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
join
a_owner o on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Now we’re ready to move the join conditions from the “where”
clause to the “from” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
join
a_owner o on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Our first join is between a_marina and a_marina_slip
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
First join is between
a_marina and
a_marina_slip
join
a_owner o on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Joining a_marina_slip to a_marina
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
We find the join condition(s)
between these two tables in the
“where” clause and move it up
into the “from” clause
join
a_owner o on
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Now we need to join a_owner to something
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
where
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
Now we need to join a_owner to something
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
where
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
We can join a_owner to
any of the tables stated
earlier in the query. a
join to a_marina_slip is
the only one that makes
sense because it is
directly related to
a_owner
Joining a_owner to a_marina_slip
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
where
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
We find the join
condition(s) between
these two tables in the
“where” clause and move
it up into the “from”
clause
Joining a_owner to a_marina_slip
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
o.owner_num = s.owner_num
where
s.boat_type like 'Dolphin%'
Filter on boat_type in the “where” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
o.owner_num = s.owner_num
where
s.boat_type like 'Dolphin%'
Because this query
involves only inner joins
we can filter in the
“where” clause (like we
are here) and the query
will yield the same
results as filtering in the
“from” clause.
This is a valid query that
performs the joins in the
“from” clause.
Filter on boat_type in the “from” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
o.owner_num = s.owner_num
where
s.boat_type like 'Dolphin%'
Alternatively we can
move the filter on
boat_type from the
“where” clause up into
the “from” clause in
either of these two spots
Filter on boat_type in the “from” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_owner o on
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
or
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num and
s.boat_type like 'Dolphin%'
join
a_owner o on
o.owner_num = s.owner_num
Both of these are valid queries performing the joins and filtering in the “from” clause
These 4 queries yield the same result set
Original query joining in the “where” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m,
a_owner o,
a_marina_slip s
where
m.marina_num = s.marina_num and
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
New queries joining in the “from” clause
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
Select
m.name,
s.boat_name,
o.first_name,
o.last_name
from
a_marina m
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_marina_slip s on
m.marina_num = s.marina_num
join
a_marina_slip s on
m.marina_num = s.marina_num and
s.boat_type like 'Dolphin%'
join
a_owner o on
o.owner_num = s.owner_num
join
a_owner o on
o.owner_num = s.owner_num and
s.boat_type like 'Dolphin%'
where
s.boat_type like 'Dolphin%'
join
a_owner o on
o.owner_num = s.owner_num