Wolf-Tilo Balke Joachim Selke Institut für Informationssysteme Technische Universität Braunschweig www.ifis.cs.tu-bs.de Relational Database Systems 1 • Implementing the relational model • SQL – Queries • SELECT – Data manipulation language (next lecture) • INSERT • UPDATE • DELETE – Data definition language (next lecture) • CREATE TABLE • ALTER TABLE • DROP TABLE Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 2 Overview • A hotel database: Hotel(hotelNo , hotelName, city) Room(roomNo , hotelNo → Hotel, type, price) Booking(hotelNo → Hotel/Room, guestNo → Guest, dateFrom , dateTo, roomNo → Room) Guest(guestNo , guestName, guestAddress) Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 3 Exercise 6.1 • Give relational algebra expressions for the following queries in natural language: a) Create a list of all hotels that includes the total number of rooms for each hotel. π hotelName, count roomNo ( hotelNo, hotelName count(roomNo) (Hotel ⋈ Room)) • Of course, this does not work for hotels without any rooms. However, let‟s assume that there is no such hotel ... b) What‟s the average room price at the Balke Inn? π average price (average(price) ( ς hotelName = „Balke Inn‟ (Hotel) ⋈ Room)) Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 4 Exercise 6.1 c) How many different people made a reservation for a room whose price is higher than the average room price at the respective hotel? AvgPrice ≔π hotelNo, average price ( hotelNo average(price) (Hotel ⋈ Room)) ExpensiveRooms ≔ π hotelNo, roomNo (ς price > average price (Room ⋈ AvgPrice)) RichGuests = π guestNo (Booking ⋈ ExpensiveRooms) Result = count(guestNo) RichGuests Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 5 Exercise 6.1 • Describe (using natural language) the relations that would be produced by the following tuple relational calculus expressions: a) { H.hotelName | hotel(H) ∧ H.city = „Braunschweig‟ } List the names of all hotels in Braunschweig! b) { H.hotelName | Hotel(H) ∧ ∃R ( Room(R) ∧ H.hotelNo = R.hotelNo ∧ R.price > 50)} List the names of all hotels offering a room that costs more than €50! Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 6 Exercise 6.2
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Wolf-Tilo Balke
Joachim Selke
Institut für Informationssysteme
Technische Universität Braunschweig
www.ifis.cs.tu-bs.de
Relational
Database Systems 1
• Implementing the relational model
• SQL
– Queries
• SELECT
– Data manipulation language (next lecture)
• INSERT
• UPDATE
• DELETE
– Data definition language (next lecture)
• CREATE TABLE
• ALTER TABLE
• DROP TABLE
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 2
Overview
• A hotel database:
Hotel(hotelNo, hotelName, city)
Room(roomNo, hotelNo → Hotel, type, price)
Booking(hotelNo → Hotel/Room, guestNo → Guest,
dateFrom, dateTo, roomNo → Room)
Guest(guestNo, guestName, guestAddress)
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 3
Exercise 6.1
• Give relational algebra expressions for the following queries in natural language:
a) Create a list of all hotels that includes the total number of rooms for each hotel.
πhotelName, count roomNo(
hotelNo, hotelName𝔉count(roomNo) (Hotel ⋈ Room))
• Of course, this does not work for hotels without any rooms. However, let‟s assume that there is no such hotel ...
b) What‟s the average room price at the Balke Inn?
πaverage price(𝔉average(price) (
ςhotelName = „Balke Inn‟(Hotel) ⋈ Room))
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 4
Exercise 6.1
c) How many different people made a reservation for a
room whose price is higher than the average room
price at the respective hotel?
AvgPrice ≔ πhotelNo, average price(
hotelNo𝔉average(price) (Hotel ⋈ Room))
ExpensiveRooms ≔πhotelNo, roomNo(ςprice > average price(Room ⋈ AvgPrice))
RichGuests = πguestNo(Booking ⋈ ExpensiveRooms)
Result = 𝔉count(guestNo)RichGuests
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 5
Exercise 6.1
• Describe (using natural language) the relations
that would be produced by the following
tuple relational calculus expressions:
a) { H.hotelName | hotel(H) ∧ H.city = „Braunschweig‟ }
List the names of all hotels in Braunschweig!
b) { H.hotelName | Hotel(H) ∧ ∃R (
Room(R) ∧ H.hotelNo = R.hotelNo ∧ R.price > 50)}
List the names of all hotels offering a room that
costs more than €50!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 6
Exercise 6.2
c) { H.hotelName | Hotel(H) ∧ ∃B ∃G (
Booking(B) ∧ Guest(G) ∧ H.hotelNo = B.hotelNo
∧ B.guestNo = G.guestNo
∧ G.guestName = „Wolf-Tilo Balke‟)}
List the names of all hotels in that Wolf-Tilo Balke
has or had a reservation!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 7
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 62
7.4 Conditions
expressionexpression
NOTNOT
NULLNULLISIS
• LIKE predicate:– The predicate is for matching character strings to patterns
– Match expression must be a character string
– Pattern expression is a (usually constant) string• May not contain column names
– Escape expression is just a single character
– During evaluation, the match expression is compared to the pattern expression with following additions• _ in the pattern expression represents any single character
• % represents any number of arbitrary characters
• The escape character prevents the special semantics of _ and %
– Most modern database nowadays also support more powerful regular expressions (introduced in SQL-99)
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 63
7.4 Conditionsmatch
expression
match
expression
pattern
expression
pattern
expressionLIKELIKE
escape
expression
escape
expressionESCAPEESCAPENOTNOT
• Examples:– address LIKE ’%City%’
• ’Manhattan’ → FALSE• ’Gotham City Prison’ → TRUE
– name LIKE ’M%_t_’• ’Magneto’ → TRUE• ’Matt’ → TRUE• ’Mtt’ → FALSE
– status LIKE ’_/_%’ ESCAPE ’/’• ’1_inPrison’ → TRUE• ’1–inPrison’ → FALSE• ’%_%’ → TRUE• ’%%%’ → FALSE
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 64
7.4 Conditions
match
expression
match
expression
pattern
expression
pattern
expressionLIKELIKE
escape
expression
escape
expressionESCAPEESCAPENOTNOT
• IN predicate:
– Evaluates to true if the value of the test expression is
within a given set of values
– Particularly useful when used with a subquery (later)
– Examples:
• name IN (’Magneto’, ’Batman’, ’Dr. Doom’)
• name IN (SELECT title FROM movies)– Those people having a film named after them…
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 65
7.4 Conditions
expressionexpression
NOTNOT
ININ
queryquery(( ))
(( ))expressionexpression
,,
• EXISTS predicate:
– Evaluates to TRUE if a given subquery
returns at least one result row
• Always returns either TRUE or FALSE
– Examples
• EXISTS (SELECT * FROM heroes)
– EXISTS may also be used to express semi-joins
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 66
7.4 Conditions
EXISTSEXISTS queryquery(( ))
• SOME/ANY and ALL:
– Compares an expression to each value provided bya subquery
– TRUE if
• SOME/ANY: At least one comparison returns TRUE
• ALL: All comparisons return TRUE
– Examples:
• result <= ALL (SELECT result FROM results)– TRUE if the current result is the smallest one
• result < SOME (SELECT result FROM results)– TRUE if the current result is not the largest one
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 67
7.4 Conditions
expressionexpression comparisoncomparison
SOMESOME
ANYANYALLALL
queryquery(( ))
• Also, SQL can do joins of multiple tables
• Traditionally, this is performed by simply stating
multiple tables in the FROM clause
– Result contains all possible combinations of all
rows of all tables such that the search condition holds
– If there is no WHERE clause, it‟s a Cartesian product
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 68
7.5 Joins
• Example:
– SELECT * FROM hero, hasAlias
• hero × hasAlias
– SELECT * FROM hero, hasAliasWHERE hero.id = hasAlias.hero_id
• hero ⋈id = hero_id hasAlias
• Besides this common implicit notation of joins,
SQL also supports explicit joins
– Inner joins
– Left/right/full outer joins
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 69
7.5 Joins
• Explicit joins are specified in the FROM clause– SELECT * FROM table1 JOIN table2 ON <join condition>
WHERE <some other condition>
– Often, attributes in joined tables have the same names,
so qualified attributes are needed
– INNER JOIN and JOIN are equivalent
• Explicit joins improve readability of your SQL code!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 70
7.5 Joins
table name
INNER JOININNER JOIN
table name
JOINJOIN
LEFT JOINLEFT JOINRIGHT JOINRIGHT JOIN
FULL JOINFULL JOIN
joined table
ONON condition
Natural join: List students and their exam results– π lastName, crsNr, result students ⋈ exams
– SELECT lastName, crsNr, resultFROM students AS s JOIN exams AS e ON s.matNr = e.matNr
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 71
7.5 Joins
matNr firstName lastName sex
1005 Clark Kent m
2832 Louise Lane f
4512 Lex Luther m
5119 Charles Xavier m
matNr crsNr result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 1.3
students exams
lastName crsNr result
Kent 100 1.3
Kent 101 4.0
Lane 102 2.0
πlastName, crsNr, result students ⋈exams
We lost Lex Luther and Charles Xavier
because they didn’t take any exams!
Also information on student 9876 disappears…
Left outer join: List students and their exam results– π lastName, crsNr, result students ⎧ exams
– SELECT lastName, crsNr, resultFROM students AS s LEFT JOIN exams AS e ON s.matNr = e.MatNr
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 72
7.5 Joins
matNr firstName lastName sex
1005 Clark Kent m
2832 Louise Lane f
4512 Lex Luther m
5119 Charles Xavier m
matNr crsNr result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 1.3
students exams
lastName crsNr result
Kent 100 1.3
Kent 101 4.0
Lane 102 2.0
Luther NULL NULL
Xavier NULL NULL
π lastName, crsNr, result students ⎧exams
Right outer join:– π lastName, crsNr, result students ⎨ exams
– SELECT lastName, crsNr, resultFROM students s RIGHT JOIN exams e ON s.matNr = e.MatNr
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 73
7.5 Joins
matNr firstName lastName sex
1005 Clark Kent m
2832 Louise Lane f
4512 Lex Luther m
5119 Charles Xavier m
matNr crsNr result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 1.3
students exams
lastName crsNr result
Kent 100 1.3
Kent 101 4.0
Lane 102 2.0
NULL 100 3.7
π lastName, crsNr, result students ⎨ exams
Full outer join:– π lastName, crsNr, result students ⎩ exams
– SELECT lastName, crsNr, resultFROM students s FULL JOIN exams e ON s.matNr = e.MatNr
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 74
7.5 Joins
matNr firstName lastName sex
1005 Clark Kent m
2832 Louise Lane f
4512 Lex Luther m
5119 Charles Xavier m
matNr crsNr result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 1.3
students exams
lastName crsNr result
Kent 100 1.3
Kent 101 4.0
Lane 102 2.0
Luther NULL NULL
NULL 100 3.7
Xavier NULL NULL
π lastName, crsNr, result students ⎩ exams
• SQL also supports the common set operators
– Set union ∪: UNION
– Set intersection ∩ : INTERSECT
– Set difference ∖: EXCEPT
• By default, set operators eliminate duplicates unlessthe ALL modifier is used
• Sets need to be union-compatible to use set operators
– Row definition must match (data types)
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 75
7.6 Set Operators
queryINTERSECTINTERSECT
queryquery-block
literal table
(( ))
EXCEPTEXCEPT
UNIONUNION
ALLALL queryquery
query-blockquery-block
literal tableliteral table
(( ))
• Example:
( SELECT course, result FROM exams WHERE course= 100
EXCEPTSELECT course, result FROM exams WHERE result IS NULL)
UNIONVALUES (100, 2.3), (100, 1.7)
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 76
7.6 Set Operators
student course result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 NULL
6676 102 4.3
3412 NULL NULL
exams
course result
100 3.7
100 2.3
100 1.7
query block query
}literal table
• Column functions are used to performstatistical computations
– Similar to aggregate function in relational algebra
– Column functions are expressions
– They compute a scalar value for a set of values
• Examples:
– Compute the average score over all exams
– Count the number of exams each student has taken
– Retrieve the best student
– ...
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 77
7.7 Column Function
• Column functions in the SQL standard:– MIN, MAX, AVG, COUNT, SUM:
Each of these are applied to some other expression• NULL values are ignored
• Function columns in result set just get their column number as name
– If DISTINCT is specified, duplicates are eliminated in advance• By default, duplicates are not eliminated (ALL)
– COUNT may also be applied to *• Simply counts the number of rows
– Typically, there are many more column functions available in your RDBMS (e.g. in DB2: CORRELATION, STDDEV, VARIANCE, ...)
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 78
7.7 Column Function
function
name
function
name
column functionexpression
COUNT(*)COUNT(*)
(( ))
ALLALL
DISTINCTDISTINCT
expression
• Examples:
– SELECT COUNT(*) FROM heroes
• Returns the number of rows of the heroes table
– SELECT COUNT(name), COUNT(DISTINCT name) FROM heroes
• Returns the number of rows in the heroes table for that
name is not null and the number of non-null unique names
– SELECT MIN(strength), MAX(strength), AVG(strength) FROM powers
• Returns the minimal, maximal, and average power strength
in the powers table
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 79
7.7 Column Function
• Similar to aggregation in relation algebra,
SQL supports grouping
– GROUP BY <column names>
– Creates a group for each combination of
distinct values within the provided columns
– A query containing GROUP BY can access
non-group-by-attributes only by column functions
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 80
7.7 Grouping
Examples:
– SELECT course, AVG(result), COUNT(*), COUNT(result) FROM exams GROUP BY course
• For each course, list the average result,
the number of results, and the number of non-null results
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 81
7.7 Grouping
student course Result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 NULL
6676 102 4.3
3412 NULL NULL
exams
course 2 3 4
100 3,7 2 1
101 4.0 1 1
102 3.15 2 2
NULL NULL 1 0
Examples:
– SELECT course, AVG(result), COUNT(*)FROM exams WHERE course IS NOT NULLGROUP BY course
• The where clause is evaluated before the groups are formed!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 82
7.7 Grouping
student course Result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 NULL
6676 102 4.3
3412 NULL NULL
exams
course 2 3
100 3.7 2
101 4.0 1
102 3.15 2
• Additionally, there may be restrictions on
the groups themselves
– HAVING <condition>
– The condition may involve group properties
– Only those groups are created that fulfill the
HAVING condition
– A query may have a WHERE and a HAVING clause
– Also, it is possible to have HAVING without GROUP BY
• Then, the whole table is treated as a single group
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 83
7.7 Grouping
• Examples:
– SELECT course, AVG(result), COUNT(*)FROM exams WHERE course <> 100GROUP BY course HAVING count(*) > 1
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 84
7.7 Grouping
student course Result
9876 100 3.7
2832 102 2.0
1005 101 4.0
1005 100 NULL
6676 102 4.3
3412 NULL NULL
exams
course 1 2
102 3.15 2
• As last step in the processing pipeline,(unordered) result sets may be converted into lists– Impose an order on the rows
– This concludes the SELECT statement
– ORDER BY keyword
• Please note:Ordering completely breaks with set calculus/algebra– Result after ordering is a list, not a (multi-)set!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 85
7.8 Ordering
SELECT statement
query
column namecolumn nameODER BYODER BY
integer
ASCASC
DESCDESC
,,
• ORDER BY may order ascending or descending
– Default: ascending
• Ordering on multiple columns possible
• Columns used for ordering arereferences by their name
• Example
– SELECT * FROM resultsORDER BY student, crsNo DESC
– Returns all results ordered by student id (ascending)
– If student ids are identical, we sort in descending orderby course number
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 86
7.8 Ordering
• When working with result lists, often only the
top-k results are of interest (e.g. k = 10)
• How can we limit the number of result rows?
– Since SQL:2008, the SQL standard offers the
FETCH FIRST clause (supported e.g. in DB2)
– Example:
SELECT name, salary FROM salariesORDER BY salary FETCH FIRST 10 ROWS ONLY
– FETCH FIRST can also be used without ORDER BY
• Get a quick impression of the result set
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 87
7.8 Ordering
• SQL queries are evaluated in this sequence:
5. SELECT <attribute list>
1. FROM <table list>
2. [WHERE <condition>]
3. [GROUP BY <attribute list>]
4. [HAVING <condition>]
6. [UNION/INTERSECT/EXCEPT <query>]
7. [ORDER BY <attribute list>]
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 88
7.8 Evaluation Order of SQL
• In SQL, you may embed a query block within
a query block (so called subquery, or nested query)
– Subqueries are written in parenthesis
– Literal subqueries can be used as expressions
• Return just one single value
– Subqueries may create the test set for the IN-condition
– Subqueries may create the test set for the
EXISTS-condition
– Each subquery within the table list creates
a temporary source table
• Called inline view
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 89
7.9 Subqueries
• Subqueries may either be correlated
or uncorrelated
– If the WHERE clause of the inner query uses an
attributes within a table declared in the outer query,
the two queries are correlated
• The inner query needs to be re-evaluated for every tuple
in the outer query
• This is rather inefficient, so avoid correlated subqueries
whenever possible!
– Otherwise, the queries are uncorrelated
• The inner queries needs to be evaluated just once
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 90
7.9 Subqueries
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 91
7.9 Subqueries
id realNameHero
hero_id aliasNameHasAlias
hero_id power_id powerStrengthHasPower
id name descriptionPower
• Expressions:
– SELECT hero.* FROM hero, hasPower pWHERE hero.id = p.hero_id
AND powerStrenth =(SELECT MAX(powerStrength) FROM hasPower)• Select all those heroes having powers with maximal strength
• Uncorrelated! Subquery is evaluated only once
• IN-condition:
– SELECT * FROM hero WHERE id IN(SELECT hero_id FROM hasAlias
WHERE aliasName LIKE ’Super%’)• Select all those heroes having an alias starting with “Super”
• Uncorrelated
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 92
7.9 Subqueries
• EXISTS-condition:
– SELECT * FROM hero hWHERE EXISTS
(SELECT * FROM hasAlias a WHERE h.id = a.hero_id)• Select heroes having at least one alias
• Correlated! Subquery is evaluated for each tuple in hero
• Inline view
– SELECT h.realName, a.aliasNameFROM hasAlias a,(SELECT * FROM heroes WHERE realName LIKE ’A%’) h WHERE h.id < 100 AND a.hero_id = h.id• Get realName–alias pairs for all heroes with a real name staring
with “A” and an id smaller than 100
• Uncorrelated
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 93
7.9 Subqueries
• What is “good” SQL code?
– Easy to read
– Easy to write
– Easy to understand!
• There is no “official” SQL style guide,
but here are some general hints
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 94
7.10 Writing Good SQL Code
1. Write SQL keywords in uppercase,
names in lowercase!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 95
SELECT movie_title title, movie_year yearFROM movies m, genres gWHERE m.movie_id = g.movie_idAND g.genre = ’Action’
4. Separate joins from conditions!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 98
7.10 Writing Good SQL Code
GOOD
BAD
SELECT movie_title title, movie_year yearFROM movies m, genres g, actors aWHERE m.movie_id = g.movie_idAND g.genre = ’Action’AND m.movie_id = a.movie_idAND a.person_name LIKE ’%Schwarzenegger%’
SELECT movie_title title, movie_year yearFROM movies mJOIN genres g ON m.movie_id = g.movie_idJOIN actors a ON g.movie_id = a.movie_idWHERE g.genre = ’Action’AND a.person_name LIKE ’%Schwarzenegger%’
5. Use proper indentation!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 99
7.10 Writing Good SQL Code
GOOD
BAD
SELECT movie_title title, movie_year yearFROM movies m, genres g, actors aWHERE m.movie_id = g.movie_idAND g.genre = ’Action’AND m.movie_id = a.movie_idAND a.person_name LIKE ’%Schwarzenegger%’
SELECT movie_title title, movie_year yearFROM movies m
JOIN genres g ON m.movie_id = g.movie_idJOIN actors a ON g.movie_id = a.movie_id
WHERE g.genre = ’Action’AND a.person_name LIKE ’%Schwarzenegger%’
6. Extract uncorrelated subqueries!
Relational Database Systems 1 – Wolf-Tilo Balke – Institut für Informationssysteme – TU Braunschweig 100
7.10 Writing Good SQL Code
GOOD
BAD
WITH recent_actors (person_id) AS(SELECT DISTINCT person_id
FROM actors aJOIN movies m ON a.movie_id = m.movie_id
WHERE movie_year >= 2007)SELECT DISTINCT person_name nameFROM directors dWHERE d.person_id IN (SELECT * FROM recent_actors)