0% found this document useful (0 votes)
8 views

SQL Slides Updated

Uploaded by

oguztemelli
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

SQL Slides Updated

Uploaded by

oguztemelli
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 118

LECTURE 4: SQL

THESE SLIDES ARE BASED ON YOUR TEXT


BOOK
SQL
 A standard for querying relational data
 Basic query structure

SELECT [DISTINCT] attribute-list


FROM relation-list
WHERE condition

DISTINCT is an optional keyword indicating that
duplicates should be eliminated. (Otherwise
duplicate elimination is not done)
SQL
 A standard for querying relational data
 Basic query structure

SELECT [DISTINCT] attribute-list


FROM relation-list
WHERE condition

 Comparisons (Attr op const or Attr1 op


Attr2, where op is one of
) combined using AND, OR and NOT.
Conceptual Evaluation
Strategy
 Semantics of an SQL query defined in terms of the
following conceptual evaluation strategy:
 Compute the cross-product of relation-list.
 Discard resulting tuples if they do not satisfy the conditions.
 Display attributes that are in attribute-list.
 If DISTINCT is specified, eliminate duplicate rows.
 This strategy is probably the least efficient way to
compute a query! An optimizer will find more
efficient strategies to compute the same answers.
Lets remember the Sailors
Example of Conceptual Evaluation on
Sailors
SELECT sname
FROM Sailors, Reserves Query: Find
WHERE Sailors.sid=Reserves.sid AND bid=103 names of sailors
who
⋈ Reserved boat
number 103
Range Variables
Query: Find
names of sailors
who
Reserved boat
number 103

SELECT sname
FROM Sailors, Reserves
WHERE Sailors.sid=Reserves.sid AND bid=103

Range variables are


SELECT S.sname necessary when joining
FROM Sailors S, Reserves R a table with itself !!!
WHERE S.sid=R.sid AND bid=103
Flash back: ER and
ER2Relational
sname

gpa
sid

Student

supervise supervisee

supervise
STUDENTS(SID, SNAME, GPA, SUPERID)
SUPERID is a foreign key referencing SID in
STUDENTS
Query: Find names of students
who
are a supervisor of some student
Expressions and Strings
SELECT S.age, age1=S.age-5, 2*S.age AS age2
FROM Sailors S
WHERE S.sname LIKE ‘B_%B’
 Illustrates use of arithmetic expressions and string
pattern matching: Find triples (of ages of sailors and
two fields defined by expressions) for sailors whose
names begin and end with B and contain at least three
characters.

AS and = are two ways to name fields in result.

LIKE is used for string matching. `_’ stands for any one
character and `%’ stands for 0 or more arbitrary
characters.
Find names of sailors who’ve reserved a red or
a green boat
SELECT R.sid
FROM Boats B, Reserves R
WHERE R.bid=B.bid
AND (B.color=‘red’ OR B.color=‘green’

SELECT R.sid

UNION: Can be used to FROM Boats B, Reserves R
compute the union of any WHERE R.bid=B.bid
two union-compatible sets of AND B.color=‘red’
tuples (which are themselves UNION
the result of SQL queries). SELECT R.sid
FROM Boats B, Reserves R
WHERE R.bid=B.bid
AND B.color=‘green’
SELECT R.sid
FROM Boats B, Reserves R
 EXCEPT : Used to compute the
WHERE R.bid=B.bid
set difference of two union-
AND B.color=‘red’
compatible sets of tuples EXCEPT
 What do we get if we replace SELECT R.sid
UNION with EXCEPT in the FROM Boats B, Reserves R
previous SQL query? WHERE R.bid=B.bid
AND B.color=‘green’
Find sid’s of sailors who’ve reserved a red and a green boat

B1 X R1
R1
B1 BID Colr SID BID
SID BID b1 red s1 b1
BID Colr
s1 b1 b1 red s1 b2
b1 red
b2 grn
s1 b2 b1 red s2 b1
s2 b1 b2 grn s1 b1
b2 grn s1 b2
b2 grn s2 b1
Find sid’s of sailors who’ve reserved
a R2 X B1 X R1
red and a green boat SID BID BID Colr SID BID
S1 b1 b1 red s1 b1

s1 b1 b1 red s1 b2

S1 b1 b1 red s2 b1

s1 b1 b2 grn s1 b1
R2 B1 X R1
s1 b1 b2 grn s1 b2
SID BID BID Colr SID BID
s1 b1 b2 grn s2 b1
b1 red s1 b1
s1 b1
b1 red s1 b2 s1 b2 b1 red s1 b1
s1 b2
b1 red s2 b1 s1 b2 b1 red s1 b2
s2 b1
b2 grn s1 b1 s1 b2 b1 red s2 b1

b2 grn s1 b2 s1 b2 b2 grn s1 b1
b2 grn s2 b1 s1 b2 b2 grn s1 b2
s1 b2 b2 grn s2 b1
s2 b1 b1 red s1 b1

s2 b1 b1 red s1 b2

s2 b1 b1 red s2 b1

s2 b1 b2 grn s1 b1
s2 b1 b2 grn s1 b2
s2 b1 b2 grn s2 b1
B2X R2 X B1 X R1
BID Colr SID BID BID Colr SID BID
SID BID BID Colr SID BID b1 red s1 b1 b1 red s1 b1

s1 b1 b1 red s1 b1 b1 red s1 b1 b1 red s1 b2

s1 b1 b1 red s1 b2 b1 red s1 b1 b1 red s2 b1

S1 b1 b1 red s2 b1 b1 red s1 b1 b2 grn s1 b1


B2 s1 b1 b2 grn s1 b1 b1 red s1 b1 b2 grn s1 b2
s1 b1 b2 grn s1 b2 b1 red s1 b1 b2 grn s2 b1
BID Colr
s1 b1 b2 grn s2 b1 b1 red b1 red s1 b1
b1 red s1 b2
s1 b2 b1 red s1 b1 b1 red b1 red s1 b2
b2 grn s1 b2
s1 b2 b1 red s1 b2
b1 red s1 b2 b1 red s2 b1
s1 b2 b1 red s2 b1
b1 red s1 b2 b2 grn s1 b1
s1 b2 b2 grn s1 b1 b1 red s1 b2 b2 grn s1 b2
s1 b2 b2 grn s1 b2
b1 red s1 b2 b2 grn s2 b1
s1 b2 b2 grn s2 b1
b1 red s2 b1 b1 red s1 b1
s2 b1 b1 red s1 b1
b1 red s2 b1 b1 red s1 b2
s2 b1 b1 red s1 b2
b1 red s2 b1 b1 red s2 b1
s2 b1 b1 red s2 b1
b1 red s2 b1 b2 grn s1 b1
s2 b1 b2 grn s1 b1
b1 red s2 b1 b2 grn s1 b2
s2 b1 b2 grn s1 b2
b1 red s2 b1 b2 grn s2 b1
s2 b1 b2 grn s2 b1
SELECT R.sid B2X R2 X B1 X R1
FROM Boats B1, Reserves R1, Boats B2,
Reserves R2 BID Colr SID BID BID Colr SID BID
WHERE R1.sid = R2.sid AND R1.bid=B1.bid b2 grn b1 red s1 b1
s1 b1
AND R2.bid=B2.bid
b2 grn s1 b1 b1 red s1 b2
AND (B1.color=‘red’ AND B2.color=‘green’)
b2 grn s1 b1 b1 red s2 b1

b2 grn s1 b1 b2 grn s1 b1
b2 grn s1 b1 b2 grn s1 b2
b2 grn s1 b1 b2 grn s2 b1
b2 grn s1 b2 b1 red s1 b1

b2 grn s1 b2 b1 red s1 b2

b2 grn s1 b2 b1 red s2 b1

b2 grn s1 b2 b2 grn s1 b1
b2 grn s1 b2 b2 grn s1 b2
b2 grn s1 b2 b2 grn s2 b1
b2 grn s2 b1 b1 red s1 b1

b2 grn s2 b1 b1 red s1 b2

b2 grn s2 b1 b1 red s2 b1

b2 grn s2 b1 b2 grn s1 b1
b2 grn s2 b1 b2 grn s1 b2
b2 grn s2 b1 b2 grn s2 b1
Find sid’s of sailors who’ve reserved a red and a
green boat SELECT R.sid
FROM Boats B1, Reserves R1,
Boats B2, Reserves R2
WHERE R1.sid = R2.sid AND
R1.bid=B1.bid AND R2.bid=B2.bid
AND (B1.color=‘red’ AND B2.color=‘green’)

INTERSECT: Can be used
to compute the
intersection of any two
SELECT R.sid
union-compatible sets of
FROM Boats B, Reserves R
tuples.
WHERE R.bid=B.bid
 Included in the SQL/92 AND B.color=‘red’
standard, but some INTERSECT
systems don’t support it. SELECT R.sid
FROM Boats B, Reserves R
WHERE R.bid=B.bid
AND B.color=‘green’
Nested Queries
Find names of sailors who’ve reserved boat #
SELECT S.sname
FROM Sailors S
WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)

WHERE clause can itself contain an SQL query! (As well as FROM and
HAVING clauses which we will see later on.)
 To understand semantics of nested queries, think of a nested loops
evaluation: For each Sailors tuple, check the qualification by computing
the subquery.

For (i=1…10) do {
x=x+1;
For (j=1…5) do {
y=y+1;
}
}
Nested Queries SELECT S.sname
FROM Sailors S
names of sailors who’ve reserved boat #103:
WHERE S.sid IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)
Nested Queries Find names of sailors
who did NOT reserve boat #103:
SELECT S.sname
FROM Sailors S
WHERE S.sid NOT IN (SELECT R.sid
FROM Reserves R
WHERE R.bid=103)
Nested Queries
Find names of sailors
with Correlation who’ve reserved boat #103:

We can use EXISTS operator which is another set comparison operator, like
IN.
SELECT S.sname
FROM Sailors S
WHERE EXISTS (SELECT *
FROM Reserves R
WHERE R.bid=103 AND S.sid=R.sid)
Nested Queries with Correlation
d names of sailors who reserved a boat at most once

 UNIQUE construct can be used.



UNIQUE checks for duplicate tuples. Returns TRUE if the
corresponding set does not contain duplicates.

SELECT S.sname
FROM Sailors S
WHERE UNIQUE ( SELECT R.bid
FROM Reserves R
WHERE S.sid=R.sid)
More on Set-Comparison
Operators
 We’ve already seen IN, EXISTS and UNIQUE. Can also use NO
IN, NOT EXISTS and NOT UNIQUE.
 Also available: op ANY, op ALL
 Find sailors whose rating is greater than that of some
sailor called Horatio:

SELECT *
FROM Sailors S
WHERE S.rating > ANY (SELECT S2.rating
FROM Sailors S2
WHERE S2.sname=‘Horatio’)
Rewriting INTERSECT Queries Using
IN
Find names of sailors who’ve reserved both a red
and a green boat:

ECT S.name
OM Sailors S, Boats B, Reserves R
ERE S.sid=R.sid AND R.bid=B.bid AND B.color=‘red’
AND S.sid IN (SELECT S2.sid
FROM Sailors S2, Boats B2, Reserves R
WHERE S2.sid=R2.sid AND R2.bid=B2.b
AND B2.color=‘green’)
How would you rewrite queries with
EXCEPT construct?


EXCEPT queries can be re-written using NOT IN.
Division in SQL
ind sailors who’ve reserved all boats.
SELECT S.sname
FROM Sailors S
WHERE NOT EXISTS
((SELECT B.bid
FROM Boats B)
EXCEPT
(SELECT R.bid
FROM Reserves R
WHERE R.sid = S.sid))
Division in SQL
ind sailors who’ve reserved all boats.
 How can we do it without EXCEPT?

LECT S.sname
OM Sailors S
HERE NOT EXISTS (SELECT B.bid
FROM Boats B
WHERE NOT EXISTS (SELECT R.bid
FROM Reserves R
WHERE R.bid=B.b
AND R.sid=S.
JOINS (SQL 2003 std, source:
wikipedia)
Employee Table
Department Table LastName DepartmentID

DepartmentID DepartmentName Rafferty 31


31 Sales Jones 33
33 Engineering
Steinberg 33
34 Clerical
Robinson 34
35 Marketing
Smith 34

Jasper 36
Inner Joins
SELECT *
FROM employee INNER JOIN department
ON employee.DepartmentID = department.DepartmentID

SELECT *
FROM employee, department
WHERE employee.DepartmentID = department.DepartmentID
Inner Joins
Employee.LastName Employee.DepartmentID Department.DepartmentName Department.DepartmentID

Smith 34 Clerical 34

Jones 33 Engineering 33

Robinson 34 Clerical 34

Steinberg 33 Engineering 33

Rafferty 31 Sales 31
Joins
SELECT *
FROM employee NATURAL JOIN department

Employee.LastName DepartmentID Department.DepartmentName

Smith 34 Clerical

Jones 33 Engineering

Robinson 34 Clerical

Steinberg 33 Engineering

Rafferty 31 Sales
Joins
SELECT *
FROM employee CROSS JOIN department

SELECT *
FROM employee, department;
Joins
SELECT *
FROM employee LEFT OUTER JOIN department
ON department.DepartmentID = employee.DepartmentID

Employee. Employee. Department. Department.


LastName DepartmentID DepartmentName DepartmentID
Jones 33 Engineering 33
Rafferty 31 Sales 31
Robinson 34 Clerical 34
Smith 34 Clerical 34
Jasper 36 NULL NULL
Steinberg 33 Engineering 33
Joins
SELECT *
FROM employee FULL OUTER JOIN department
ON employee.DepartmentID = department.DepartmentID

Some DBMSs do not support FULL OUTER JOIN!


Can you implement FULL OUTER JOIN WITH LEFT and
RIGHT OUTER JOINS?
Aggregate Operators
 Significant extension of relational algebra.
 They are used to write statistical queries
 Mainly used for reporting such as
 the total sales in 2004,
 average, max, min income of employees
 Total number of employees hired/fired in 2004

COUNT (*)
COUNT ( [DISTINCT] A)
SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
MIN (A)
COUNT (*)
Aggregate Operators COUNT ( [DISTINCT] A)
SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
Total number of sailors in the club? MIN (A)

SELECT COUNT (*)


FROM Sailors S
COUNT (*)
Aggregate Operators COUNT ( [DISTINCT] A)
SUM ( [DISTINCT] A)
Average age of sailors in the club AVG ( [DISTINCT] A)
Whose rating is 10? MAX (A)
MIN (A)

SELECT AVG (S.age)


FROM Sailors S
WHERE S.rating=10
COUNT (*)
Aggregate Operators COUNT ( [DISTINCT] A)
SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
verage distinct ages of sailors in the club
hose rating is 10? MIN (A)

SELECT AVG ( DISTINCT S.age)


FROM Sailors S
WHERE S.rating=10
COUNT (*)
COUNT ( [DISTINCT] A)
Aggregate Operators SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
MIN (A)

Names of sailors whose rating is


equal to the maximum rating in the
club.
SELECT S.sname
FROM Sailors S
WHERE S.rating= (SELECT MAX(S2.rating)
FROM Sailors S2)
COUNT (*)
COUNT ( [DISTINCT] A)
Aggregate Operators SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
MIN (A)

Number of sailors whose rating is


equal to the maximum rating in the
club.
SELECT COUNT(S.sid)
FROM Sailors S
WHERE S.rating= (SELECT MAX(S2.rating)
FROM Sailors S2)
COUNT (*)
COUNT ( [DISTINCT] A)
Aggregate Operators SUM ( [DISTINCT] A)
AVG ( [DISTINCT] A)
MAX (A)
MIN (A)

How many different ratings are


there in the club?

SELECT COUNT (S.rating)


FROM Sailors S

Above query is not correct. Think


why!
SELECT COUNT (DISTINCT S.rating)
FROM Sailors S
Find name and age of the oldest
sailor(s)
SELECT S.sname, MAX (S.age)
FROM Sailors S

 This query is illegal! (We’ll see why a bit


later, when we discuss GROUP BY.)
Find name and age of the oldest
sailor(s)
 This query is correct and it is allowed in the
SQL/92 standard, but is not supported in some
systems.

SELECT S.sname, S.age


FROM Sailors S
WHERE S.age =
(SELECT MAX (S2.age)
FROM Sailors S2)
Find name and age of the oldest
sailor(s)
 This query is valid for all systems .

SELECT S.sname, S.age


FROM Sailors S
WHERE (SELECT MAX (S2.age)
FROM Sailors S2)
= S.age
GROUP BY and HAVING
 So far, we’ve applied aggregate operators to all
(qualifying) tuples. Sometimes, we want to apply
them to each of several groups of tuples.
 Consider: Find the age of the youngest sailor for
each rating level.
 In general, we don’t know how many rating levels exist,
and what the rating values for these levels are!
 Suppose we know that rating values go from 1 to 10; we
can write 10 queries that look like this (!):

SELECT MIN (S.age)


For i = 1, 2, ... , 10: FROM Sailors S
WHERE S.rating = i
Ecercises on SQL
BONUS QUESTION
10 database experts go into a restaurant and realize that
there is an empty table of size 5 and next to it there is
another empty table of size 6
WHAT DO THEY DO?
There will be many questions in
the following slides
Please draw a line from top to bottom dividing each surface
into two regions

Front Back
Write down the following schema
(mindfully)

STUDENTS(SID,NAME, AGE, GPA)


COURSES(CID,CNAME)
ENROLL(SID,CID, GRADE)
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q1: IDs of students enrolled in a course S2 CS307 A
S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q2: Names of students enrolled in a S2 CS307 A
course (Do not use IN or EXISTS) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q3: Names of students enrolled in a S2 CS307 A
course (Use IN) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q4: Names of students NOT enrolled in a S2 CS307 A
course (Use IN) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q5: Names of students enrolled in CS306 S2 CS307 A
(Do NOT use in or EXISTS) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q6: Names of students enrolled in CS306 S2 CS307 A
(use EXISTS) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q7: Names of students who got an A from S2 CS307 A
CS306 (Use IN) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q8: How many courses are offered? S2 CS307 A
S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q9: What is the average GPA? S2 CS307 A
S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q10: What are the names of the student S2 CS307 A
with maximum GPA? (use IN operator) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q11: How many courses did S1 enroll in? S2 CS307 A
S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q12: How many students are enrolled in S2 CS307 A
CS300? S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q13: What is the average GPA of students S2 CS307 A
enrolled in CS300? S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q14: IDs of students enrolled in all S2 CS307 A
courses S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q15: IDs of students enrolled in all S2 CS307 A
courses (Use EXCEPT) S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q16: IDs of students enrolled in all S2 CS307 A
courses (Use EXISTS) S3 CS300 B
Queries With GROUP BY and
HAVING
SELECT [DISTINCT] target-
list
FROM relation-list
WHERE qualification
GROUP BY grouping-list
HAVING group-
 The target-list contains (i) attribute names (ii) terms
qualification
with aggregate operations (e.g., MIN (S.age)).
 The attribute list (i) must be a subset of grouping-list.
Intuitively, each answer tuple corresponds to a group, and
these attributes must have a single value per group. (A group
is a set of tuples that have the same value for all attributes in
grouping-list.)
Conceptual Evaluation
 The cross-product of relation-list is computed, tuples
that fail qualification are discarded, `unnecessary’
fields are deleted, and the remaining tuples are
partitioned into groups by the value of attributes in
grouping-list.
 The group-qualification is then applied to eliminate
some groups. Expressions in group-qualification must
have a single value per group!
 In effect, an attribute in group-qualification that is not an
argument of an aggregate op also appears in grouping-list.
 One answer tuple is generated per qualifying group.
Conceptual SELECT [DISTINCT] target-list
FROM relation-list
Evaluation WHERE qualification
SELECT target-list
GROUP BY grouping-list
FROM relation-list
HAVING group-qualification
WHERE qualification

HAVING group-qualification
GROUP BY grouping-list
gr1

gr2

RESULT

gr3

gr4

gr5
Conceptual SELECT S.rating
FROM Sailors S
Evaluation WHERE S.age >= 18
SELECT S.rating
FROM Sailors S GROUP BY S.rating
WHERE S.age >= 18 HAVING COUNT (*) > 1
Age = 20
Age = 25
HAVING COUNT (*) > 1
Age = 19 GROUP BY S.rating
Rating=1
Age=70 gr1 Rating=1
Rating = 4
Age = 60 Rating =2
Rating =3 gr2 Rating=2
Age = 40 Rating=2 Rating=2
Rating=3 RESULT
Age = 33 Rating=5 Rating=3
Rating=1 Rating=3 Rating = 1
Age = 32 Rating=4 gr3 Rating = 2
Rating=3
Rating=3 Rating = 3
Rating=4 Rating = 4
Age = 18 Rating=1
Rating=4
gr4 Rating=4
Age = 22 Rating=4
Age = 39
gr5 Rating=5
Ecercises on SQL with Group
By
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q17: What is the number of students S2 CS307 A
enrolled in each course? S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q18: What is the average GPA of students S2 CS307 A
enrolled in each course? S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q19: For each student display the number S2 CS307 A
of courses enrolled in (by that student)? S3 CS300 B
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q19: For each student with GPA greater S2 CS307 A
than 3, display the number of courses S3 CS300 B
enrolled in (by that student)?
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q20: Display the number of students S2 CS307 A
enrolled in each course if it is a large S3 CS300 B
course with more than 2 students.
SID SNAME GPA CID CNAME SID CID GRADE
S1 Ali 2.0 CS306 DB S1 CS306 A
S2 Sara 3.5 CS307 OS S1 CS307 B
S3 Ahmet 2.5 CS300 DS S1 CS300 C
S4 Ayse 4.0 S2 CS300 A
S2 CS306 F
Q21: Display the number of high GPA S2 CS307 A
(greater than 3.5) students enrolled in S3 CS300 B
each course.
Find the age of the youngest sailor with age
18, for each rating with at least 2 such sailors

SELECT S.rating, MIN (S.age)


FROM Sailors S
WHERE S.age >= 18
GROUP BY S.rating
HAVING COUNT (*) > 1

 Only S.rating and S.age are


mentioned in the SELECT,
GROUP BY or HAVING clauses;
 2nd column of result is
unnamed. (Use AS to name
it.)
Answer relation
For each red boat, find the number of reservations for this
boat
For each red boat, find the number of reservations for this
boat

SELECT B.bid, COUNT (*) AS scount


FROM Boats B, Reserves R
WHERE R.bid=B.bid AND B.color=‘red’
GROUP BY B.bid

 What do we get if we remove B.color=‘red’ from the


WHERE clause and add a HAVING clause with this
condition?
SELECT B.bid, COUNT (*) AS scount
FROM Boats B, Reserves R
WHERE R.bid=B.bid
GROUP BY B.bid
HAVING B.color=‘red’
Find the age of the youngest sailor with age >
18, for each rating with at least 2 sailors (of
any age)
The following query:

SELECT S.rating, MIN (S.age)


FROM Sailors S
WHERE S.age > 18
GROUP BY S.rating
HAVING COUNT (*) > 1

Is not exactly right!


Find the age of the youngest sailor with age >
18, for each rating with at least 2 sailors (of
any age)
SELECT S.rating, MIN (S.age)
FROM Sailors S
WHERE S.age > 18
GROUP BY S.rating
HAVING 1 < (SELECT COUNT (*)
FROM Sailors S2
WHERE S.rating=S2.rating)

 Shows HAVING clause can also contain a subquery.


Find those ratings for which the
average age is the minimum over all
ratings
 Aggregate operations cannot be nested!
WRONG:
SELECT S.rating
FROM Sailors S
WHERE S.age = (SELECT MIN (AVG (S2.age)) FROM Sailors S2)

Correct solution (in SQL/92):


SELECT Temp.rating, Temp.avgage
FROM (SELECT S.rating, AVG (S.age) AS avgage
FROM Sailors S
GROUP BY S.rating) AS Temp
WHERE Temp.avgage = (SELECT MIN (Temp.avgage)
FROM Temp)
Null Values
 Field values in a tuple are sometimes unknown
(e.g., a rating has not been assigned) or
inapplicable (e.g., no spouse’s name).
 SQL provides a special value null for such situations.
 The presence of null complicates many issues.
E.g.:
 Special operators needed to check if value is/is not
null.
 Is rating>8 true or false when rating is equal to null?
What about AND, OR and NOT connectives?
 We need a 3-valued logic (true, false and unknown).
 Meaning of constructs must be defined carefully.
(e.g., WHERE clause eliminates rows that don’t
EMP(NAME, SSN, BDATE, ADDRESS, SALARY)
DEP(DNAME, DNUM, MGRSSN)
(MGRSSN references SSN in EMP table)
WORKSIN(SSN, DNUM, HOURS)
(DNUM references DNUM in DEP table)
(SSN reference SSN in EMP table)
Write the relational algebra expressions for the following queries:

List the names of employees who work in all departments


EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)

DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)

DEPT_LOCATIONS(DNUMBER, DLOCATION)

PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)

WORKSON(ESSN, PNO, HOURS)

DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q11: List the names of managers with at least one dependent

SELECT EMPLOYEE.NAME
FROM EMPLOYEE, DEPARTMENT
WHERE DEPARTMENT.MGRSSN = EMPLOYEE.SSN AND
EMPLOYEE.SSN IN
(SELECT DISTINCT ESSN
FROM DEPENDENT)
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q12: List the names of employees who do not work on a project controlled by
department no 5.

SELECT NAME
FROM EMPLOYEE
WHERE SSN NOT IN (SELECT WORKSON.ESSN
FROM WORKSON, PROJECT
WHERE WORKSON.PNO =
PROJECT.PNUMBER
AND PROJECT.DNUM = 5)
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)
Q13: List the names of employees who do not work on all projects controlled by
department no 5.

SELECT E.NAME
FROM WORKSON W, EMPLOYEE E
WHERE E.SSN = W.ESSN
AND EXISTS ((SELECT P.PNUMBER
FROM PROJECT P
WHERE P.DNUM = 5)
EXCEPT (SELECT W1.PNO
FROM WORKSON W1
WHERE W1.ESSN = W.ESSN))
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)
Q13: List the names of employees who do not work on all projects controlled by
department no 5.

SELECT E.NAME
FROM WORKSON W, EMPLOYEE E
WHERE E.SSN = W.ESSN
AND EXISTS (SELECT P.PNUMBER
FROM PROJECT P
WHERE P.DNUM = 5
AND NOT EXISTS (SELECT W1.ESSN
FROM WORKSON W1
WHERE W1.ESSN = W.ESSN
AND W1.PNO =
P.PNUMBER))
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q14: List the names of employees who do not have supervisors


(IS NULL checks for null values!)

SELECT NAME
FROM EMPLOYEE
WHERE SUPERSSN IS NULL
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q15: Find the SUM of the salaries of all employees, the max salary,
min salary and average salary.

SELECT SUM(SALARY) AS SALARY_SUM, MAX(SALARY) AS MAX_SALARY,


MIN(SALARY) AS MIN_SALARY, AVG(SALARY) AS AVERAGE_SALARY
FROM EMPLOYEE
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q16: Find the SUM of the salaries of all employees, the max salary,
min salary and average salary for research department.

SELECT SUM(SALARY) AS SALARY_SUM, MAX(SALARY) AS MAX_SALARY,


MIN(SALARY) AS MIN_SALARY, AVG(SALARY) AS AVERAGE_SALARY
FROM EMPLOYEE, DEPARTMENT
WHERE EMPLOYEE.DNO = DEPARTMENT.DNUMBER
AND DEPARTMENT.DNAME = 'RESEARCH'
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q17: Find the number of employees in research department.

SELECT COUNT(*) AS EMPLOYEE_COUNT


FROM EMPLOYEE, DEPARTMENT
WHERE EMPLOYEE.DNO = DEPARTMENT.DNUMBER
AND DEPARTMENT.DNAME = 'RESEARCH'
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q18: Find the number of distinct salary values for Employees.

SELECT COUNT(DISTINCT SALARY)


FROM EMPLOYEE
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q19: Display the names of the employees who do not practice birth control
(more than 5 children).

SELECT NAME
FROM EMPLOYEE
WHERE SSN IN (SELECT ESSN
FROM DEPENDENT
WHERE RELATIONSHIP = 'Child'
GROUP BY ESSN
HAVING COUNT(*) > 5)
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q20: For each department, retrieve the department number, number of employees
in that department and the average salary.

ELECT DNO, COUNT(*) AS EMPLOYEE_COUNT, AVG(SALARY) AS AVERAGE_SALARY


ROM EMPLOYEE
ROUP BY DNO
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q21: For each project, retrieve the project number, the project name, and the number
of employees who work for that project.

SELECT PROJECT.PNAME, PROJECT.PNUMBER, COUNT(*) AS EMPLOYEE_COUNT


FROM PROJECT, WORKSON
WHERE WORKSON.PNO = PROJECT.PNUMBER
GROUP BY PROJECT.PNUMBER

DO YOU SEE ANYTHING WRONG WITH THIS QUERY?


EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q21: For each project, retrieve the project number, the project name, and the number
of employees who work for that project.

SELECT PROJECT.PNAME, PROJECT.PNUMBER, COUNT(*) AS EMPLOYEE_COUNT


FROM PROJECT, WORKSON
WHERE WORKSON.PNO = PROJECT.PNUMBER
GROUP BY PROJECT.PNUMBER, PROJECT.PNAME
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q22: 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.

SELECT PROJECT.PNAME, PROJECT.PNUMBER, COUNT(*) AS EMPLOYEE_COUN


FROM PROJECT, WORKSON
WHERE WORKSON.PNO = PROJECT.PNUMBER
GROUP BY PROJECT.PNUMBER, PROJECT.PNAME
HAVING COUNT(*) > 2
EMPLOYEE(NAME, SSN, BDATE, ADDRESS, SALARY, SUPERSSN, DNO)
DEPARTMENT(DNAME, DNUMBER, MGRSSN, MGRSTARTDATE)
DEPT_LOCATIONS(DNUMBER, DLOCATION)
PROJECT(PNAME, PNUMBER, PLOCATION, DNUM)
WORKSON(ESSN, PNO, HOURS)
DEPENDENT(ESSN, DEPENDENT_NAME, SEX, BDATE, RELATIONSHIP)

Q23: For each department that has more than five employees, retrieve the department
number and the number of its employees who are making more than 40000.

SELECT DNO, COUNT(*) AS EMPLOYEE_COUNT


FROM EMPLOYEE
WHERE SALARY * 12 > 40000
AND DNO IN (SELECT DNO
FROM EMPLOYEE
GROUP BY DNO
HAVING COUNT(*) > 5)
GROUP BY DNO
Integrity Constraints

 An IC describes conditions that every legal instance of


a relation must satisfy.
 Inserts/deletes/updates that violate IC’s are disallowed.
 Can be used to ensure application semantics (e.g., sid is a
key), or prevent inconsistencies (e.g., sname has to be a
string, age must be < 200)
 Types of IC’s: Domain constraints, primary key
constraints, foreign key constraints, general
constraints.
 Domain constraints: Field values must be of right type.
Always enforced.
General Constraints
 Useful when more general ICs than keys are involved.

CREATE TABLE Sailors


( sid INTEGER,
sname CHAR(10),
rating INTEGER,
age REAL,
PRIMARY KEY (sid),
CHECK ( rating >= 1
AND rating <= 10 )
General Constraints
 Constraints can be named.
 Can use queries to express constraint.

CREATE TABLE Reserves


( sname CHAR(10),
bid INTEGER,
day DATE,
PRIMARY KEY (bid,day),
CONSTRAINT noInterlakeRes
CHECK (`Interlake’ <>
( SELECT B.bname
FROM Boats B
WHERE B.bid=bid)))
Constraints Over Multiple
Relations
CREATE TABLE Sailors
( sid INTEGER, Number of boats
sname CHAR(10), plus number of
rating INTEGER, sailors is < 100
age REAL,
PRIMARY KEY (sid),
CHECK
( (SELECT COUNT (S.sid) FROM Sailors S)
+ (SELECT COUNT (B.bid) FROM Boats B) < 100 )

 Awkward and wrong!


 If Sailors is empty, the number of Boats tuples can be
anything!
Constraints Over Multiple
Relations
 ASSERTION is the right solution; not associated with either
table.

Number of boats
plus number of
sailors is < 100

CREATE ASSERTION smallClub


CHECK
( (SELECT COUNT (S.sid) FROM Sailors S)
+ (SELECT COUNT (B.bid) FROM Boats B) < 100 )
Other Constraints: Functional
Dependencies (FDs)

 A functional dependency X Y holds over relation R if,


for every allowable instance r of R:
 t1 r, t2 r, (t1) = (t2) implies (t1) = (t2)
 i.e., given two tuples in r, if the X values agree, then the Y
values must also agree. (X and Y are sets of attributes.)

X Y Z
t1 1 a p
2 b q
t2 1 a r
2 b p
Example:

Does the following relation instance satisfy CID->CNAME ?


How can we write a constraint or assertion to check that?
SID CID CNAME
1 CS306 DB
2 CS306 DB
1 CS307 OS
2 CS307 DS
Math Functions
http://dev.mysql.com/doc/refman/5.7/en/mathematical-
functions.html
User Defined Variables
http://dev.mysql.com/doc/refman/5.7/en/user-variables.html

Enable you to pass values from one


statement to another.
Stored Procedures
http://dev.mysql.com/doc/refman/5.7/en/stored-programs-
defining.html

Enable you to write a set of statements


to be stored at the server and called
back when needed
Stored Procedures
http://dev.mysql.com/doc/refman/5.7/en/stored-programs-
defining.html

Need to redefine the delimiter “;”


Stored Procedures
http://dev.mysql.com/doc/refman/5.7/en/stored-programs-
defining.html

Calling a stored procedure


Triggers

 Trigger: procedure that starts


automatically if specified changes occur
to the DBMS
 Three parts:
 Event (activates the trigger)
 Condition (tests whether the triggers should
run)
 Action (what happens if the trigger runs)
Triggers

 Events: INSERT, UPDATE, DELETE


 Time: BEFORE or AFTER the event (the
trigger action time)
Trigger Example:
https://dev.mysql.com/doc/refman/5.5/en/trigger-
syntax.html
Trigger Example:
https://dev.mysql.com/doc/refman/5.5/en/trigger-
syntax.html
Trigger Example:
https://dev.mysql.com/doc/refman/5.5/en/trigger-
syntax.html

By using the BEGIN ... END construct, you can


define a trigger that executes multiple
statements.
Trigger Example:
https://dev.mysql.com/doc/refman/5.5/en/trigger-
syntax.html

Assumes that we have the following tables.


Trigger Example:
https://dev.mysql.com/doc/refman/5.5/en/trigger-
syntax.html

Triggers referencing those tables.

You might also like