Using Relational Databases and SQL

32
Using Relational Databases and SQL Steven Emory Department of Computer Science California State University, Los Angeles Lecture 4: Joins Part II

description

Steven Emory Department of Computer Science California State University, Los Angeles. Using Relational Databases and SQL. Lecture 4: Joins Part II. Topics for Today. Self Joins (Pages 84 - 86) ‏ Left and Right Joins (Pages 74 - 80) ‏ Mixing Inner and Outer Joins (Pages 81 - 82) ‏. - PowerPoint PPT Presentation

Transcript of Using Relational Databases and SQL

Page 1: Using Relational Databases and SQL

Using Relational Databases and SQL

Steven EmoryDepartment of Computer Science

California State University, Los Angeles

Lecture 4:Joins Part II

Page 2: Using Relational Databases and SQL

Topics for Today

Self Joins (Pages 84 - 86)

Left and Right Joins (Pages 74 - 80)

Mixing Inner and Outer Joins (Pages 81 - 82)

Page 3: Using Relational Databases and SQL

Self Joins

A self join is a table that is joined to itself

Typical case is when a foreign key references a primary key in the same table

Non-typical case is when you want to find pairs of things from within the same table

Useful for modelling hierarchical relationships within a single table

Folders: Parent-Child Hierarchy

Employees: Employee Hierarchy

Page 4: Using Relational Databases and SQL

Typical Self Joins

Employee Table:

EmployeeID (primary key)

FirstName

LastName

JobTitle

Salary

SupervisorID (foreign key references EmployeeID)

Page 5: Using Relational Databases and SQL

Typical Self Joins

#1 List all employees (first and last names) who are supervised by no one.#2 List all employees whose supervisors are supervised by no one.#3 List all employees whose supervisor’s supervisors are supervised by no one.

Page 6: Using Relational Databases and SQL

Typical Self Joins

Solutions (for #2 and #3):

SELECT E.FirstName, E.LastNameFROM Employee E JOIN Employee S ON E.SupervisorID = S.EmployeeIDWHERE S.SupervisorID IS NULL;

SELECT E.FirstName, E.LastNameFROM Employee E JOIN Employee S ON E.SupervisorID = S.EmployeeID JOIN Employee SS ON S.SupervisorID = S.EmployeeIDWHERE SS.SupervisorID IS NULL;

Page 7: Using Relational Databases and SQL

Self Joins in the Movie Database

Good news! There are no hierarchical table relationships, so no typical cases

There are, however, some non-typical self join possibilities, dealing with pairings

Page 8: Using Relational Databases and SQL

Self Joins in the Movie Database

Example

-- List all pairs of movie-related people who were born in the same city, state/province, and country. Do not pair any people with themselves and do not list duplicate pairs.

SELECT P1.FirstName, P1.LastName, '...', P2.FirstName, P2.LastNameFROM People P1 JOIN People P2 ON (P1.BirthCity = P2.BirthCity AND P1.BirthStateProvince = P2.BirthStateProvinceAND P1.BirthCountry = P2.BirthCountry)WHERE P1.PersonID < P2.PersonID;

Page 9: Using Relational Databases and SQL

Self Joins in the Movie Database

Alternate (shorter) solution:

-- List all pairs of movie-related people who were born in the same city, state/province, and country. Do not pair any people with themselves and do not list duplicate pairs.

SELECT P1.FirstName, P1.LastName, '...', P2.FirstName, P2.LastNameFROM People P1 JOIN People P2 USING(BirthCity, BirthStateProvince, BirthCountry)WHERE P1.PersonID < P2.PersonID;

Page 10: Using Relational Databases and SQL

Outer Joins: The Problem

Question: Display a list of movie-related people who are not actors.

Page 11: Using Relational Databases and SQL

Outer Joins: The Problem

Question: Display a list of movie-related people who are not actors.

Let’s try an inner join

SELECT FirstName, LastName, MovieID, CharacterNameFROM People P JOIN XRefActorsMovies AON P.PersonID = A.ActorID;

Incorrect! An inner join associates people (in P) with movie characters (in A) for which they played.

Page 12: Using Relational Databases and SQL

Outer Joins: The Problem

Question: Display a list of movie-related people who are not actors.

Let’s try negating the inner join condition

SELECT FirstName, LastName, MovieID, CharacterNameFROM People P JOIN XRefActorsMovies AON P.PersonID <> A.ActorID;

Incorrect as well! An inner join with a negated join condition associates people (in P) with movie characters (in A) for which they did not play.

Page 13: Using Relational Databases and SQL

Outer Joins: The Problem

To solve the problem, we need to know which PersonIDs in the People table ARE NOT IN the ActorID column of the XRefActorsMovies table?

Page 14: Using Relational Databases and SQL

Outer Joins: The Solution

Use an outer join

SELECT FirstName, LastNameFROM People P LEFT JOIN XRefActorsMovies AON P.PersonID = A.ActorIDWHERE ActorID IS NULL;

SELECT FirstName, LastNameFROM XRefActorsMovies A RIGHT JOIN People P ON P.PersonID = A.ActorIDWHERE ActorID IS NULL;

Can't use equi-join

Page 15: Using Relational Databases and SQL

Outer Join Definition

Outer Join Definition

Outer Join = Matching Records (Inner Join) + Zero-Matching Records (Anti Join + NULL)

Provides information about records in one table that ARE and ARE NOT in the second table

Since we must always have a complete table, NULL values are concatenated to the anti join results

Page 16: Using Relational Databases and SQL

Outer Join Visualization

Page 17: Using Relational Databases and SQL

Outer Join Types

Left Join

Every record from the left (first) table will always be listed at least once

If a matching record is found in the right (second) table, it is listed normally (same as inner join)

If there are no matching records to be found in the right (second) table (zero-matching rows), the record from the left table is still reported, albeit it is associated with NULL values in the right table.

Right Join

Same as left join, but swapping left and right

Page 18: Using Relational Databases and SQL

Outer Join Tips

If you need to use an outer join, always use a LEFT JOIN in MySQL

LEFT JOIN is same as RIGHT JOIN

Difference is do you prefer:

Joining left to right? (LEFT JOIN)

Joining right to left? (RIGHT JOIN)

Mathematical expression and the English grammar read from left to right… therefore I always prefer the LEFT JOIN!

Page 19: Using Relational Databases and SQL

Left Join Syntax

Two tables

SELECT attribute_listFROM table1 LEFT JOIN table2ON join_condition;

More than two tables

SELECT attribute_listFROM table1 LEFT JOIN table2 ON join_condition LEFT JOIN table3 ON join_condition ...

*Note that you may also use JOIN USING syntax as well…

Page 20: Using Relational Databases and SQL

Right Join Syntax

Two tables

SELECT attribute_listFROM table1 RIGHT JOIN table2ON join_condition;

More than two tables

SELECT attribute_listFROM table1 RIGHT JOIN table2 ON join_condition RIGHT JOIN table3 ON join_condition ...

*Note that you may also use JOIN USING syntax as well…

Page 21: Using Relational Databases and SQL

More Left/Right Join Syntax

NATURAL JOIN syntax

SELECT attribute_listFROM table1 NATURAL LEFT JOIN table2;

SELECT attribute_listFROM table1 NATURAL RIGHT JOIN table2;

JOIN USING syntax

SELECT attribute_listFROM table1 LEFT JOIN table2 USING(attribute);

SELECT attribute_listFROM table1 RIGHT JOIN table2 USING(attribute);

Page 22: Using Relational Databases and SQL

Outer Join Order

Join order makes a big difference

A LEFT JOIN B is not the same as B LEFT JOIN A

The expression “People (People table) who are not actors (XRefActorsMovies table)” does not say the same thing as, “Actors (XRefActorsMovies table) who are not people (People table)”

Why not?

Only SOME people are actors (A LEFT JOIN B)

However, ALL actors are people (B LEFT JOIN A)

Thus, you will get different results!

Page 23: Using Relational Databases and SQL

Outer Join Order Example

Try it and you will see that you do not get the same results!

Page 24: Using Relational Databases and SQL

Extracting Data From Outer Joins

To extract the “zero-matching” results from an outer join, you must test the primary key (from the opposite side of the outer join) for NULL

For example, for A LEFT JOIN B, to extract the records in A that have no matches in B, you must test the primary key in B (the right table) for NULL in the WHERE clause

Page 25: Using Relational Databases and SQL

Extracting Data From Outer Joins

Page 26: Using Relational Databases and SQL

Extracting Data From Outer Joins

Page 27: Using Relational Databases and SQL

Mixing Inner and Outer Joins

It is OK to mix inner joins with outer joins

Once you start an outer join, you usually have to keep doing outer joins (if you join more tables)

NULL does not match up with anything

Try the following query with mixed join types:

-- List the first and last names of ALL movie-related people along with the titles of any movies that they have starred in. If a person has not acted in any movies, just display their first and last name along with a NULL movie title.

Page 28: Using Relational Databases and SQL

Mixing Inner and Outer Joins

Solution #1: Correct

SELECT FirstName, LastName, TitleFROM People P LEFT JOIN XRefActorsMovies A ON P.PersonID = A.ActorID LEFT JOIN Movies M ON A.MovieID = M.MovieID;

Page 29: Using Relational Databases and SQL

Mixing Inner and Outer Joins

Solution #2: Incorrect

SELECT FirstName, LastName, TitleFROM People P LEFT JOIN XRefActorsMovies A ON P.PersonID = A.ActorID INNER JOIN Movies M ON A.MovieID = M.MovieID;

Page 30: Using Relational Databases and SQL

Sample Problems

#1 Produce a listing of all genres that are not associated with any movie.

#2 Report the first and last names of all movie-related people born in the US who are not producers, directors nor actors.

Page 31: Using Relational Databases and SQL

Sample Solutions

#1

SELECT G.GenreFROM Genres G LEFT JOIN XRefGenresMovies XGM ON G.Genre = XGM.GenreWHERE MovieID IS NULL;

Page 32: Using Relational Databases and SQL

Sample Solutions

#2

SELECT PersonID, FirstName, LastNameFROM People P LEFT JOIN XRefActorsMovies A ON P.PersonID = A.ActorID LEFT JOIN XRefDirectorsMovies D ON P.PersonID = D.DirectorID LEFT JOIN XRefProducersMovies R ON P.PersonID = R.ProducerIDWHERE A.ActorID IS NULL AND D.DirectorID IS NULL AND R.ProducerID IS NULL;