0% found this document useful (0 votes)
46 views54 pages

IS273: Database Systems Spring 2020 Complex SQL

This document discusses SQL queries for retrieving data from multiple tables using joins. It covers inner joins, left outer joins, right outer joins, and full outer joins. Examples are provided for each type of join using sample tables. Subqueries are also discussed, including correlated vs uncorrelated subqueries and examples of different types of subqueries. The document concludes with a brief overview of triggers in databases and provides a sample trigger to enforce a minimum salary for new professor records.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views54 pages

IS273: Database Systems Spring 2020 Complex SQL

This document discusses SQL queries for retrieving data from multiple tables using joins. It covers inner joins, left outer joins, right outer joins, and full outer joins. Examples are provided for each type of join using sample tables. Subqueries are also discussed, including correlated vs uncorrelated subqueries and examples of different types of subqueries. The document concludes with a brief overview of triggers in databases and provides a sample trigger to enforce a minimum salary for new professor records.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 54

IS273: Database Systems

Spring 2020

COMPLEX SQL
SQL for Data Retrieval:
Retrieving Information from Multiple Tables
• Joins
– One way of combining data is by using a join
• Join [also called an Inner Join]
• Left Outer Join
• Right Outer Join
• Full Outer Join
• (INNER) JOIN: Returns records that have matching values
in both tables
• LEFT (OUTER) JOIN: Returns all records from the left
table, and the matched records from the right table
• RIGHT (OUTER) JOIN: Returns all records from the right
table, and the matched records from the left table
• FULL (OUTER) JOIN: Returns all records when there is a
match in either left or right table
SQL for Data Retrieval:
JOIN…ON Example
• The JOIN…ON syntax can be used
in joins.
• It has the advantage of moving the
JOIN syntax into the FROM clause
SELECT EmpName
FROM EMPLOYEE AS E JOIN DEPARTMENT AS D
ON E.DeptID = D.DeptID
WHERE D.DeptName LIKE 'Account%';
SQL for Data Retrieval:
Tables used for SQL Examples
SQL for Data Retrieval:
Join Example
• Inner join
 Default type of join in a joined table
 Tuple is included in the result only if a matching
tuple exists in the other relation
SELECT * from Students S INNER JOIN Advisors
A ON S.Advisor_ID = A.Advisor_ID
SQL for Data Retrieval:
OUTER JOIN
• The OUTER JOIN syntax can be used to obtain data
that exists in one table without matching data in the
other table.
• LEFT OUTER JOIN
– Every tuple in left table must appear in result
– If no matching tuple
• Padded with NULL values for attributes of right table
• RIGHT OUTER JOIN
– Every tuple in right table must appear in result
– If no matching tuple
• Padded with NULL values for the attributes of left table
• FULL OUTER JOIN
– A full join is also known as a full outer join
– It combines the features of both a Left and Right outer join
SQL for Data Retrieval:
LEFT OUTER JOIN Example
SELECT * from Students S LEFT OUTER JOIN
Advisors A ON S.Advisor_ID=A.Advisor_ID
SQL for Data Retrieval:
FULL OUTER JOIN Example
SELECT * from Students S FULL OUTER JOIN
Advisors A ON S.Advisor_ID=A.Advisor_ID
SQL for Data Retrieval:
Retrieving Information from Multiple Tables

• Subquery – placing an inner query (SELECT


statement) inside an outer query
• Options:
– In a condition of the WHERE clause
– As a “table” of the FROM clause
– Within the HAVING clause
• Subqueries can be:
– Noncorrelated – executed once for the entire outer
query
– Correlated – executed once for each row returned
by the outer query

9
Motivation for Subqueries
• Find the name of the professor who teaches “CS
4604.”
SELECT Name
FROM Professors, Teach
WHERE (PID = ProfessorPID) AND (Number = ‘4604’)
AND(DeptName = ‘CS’) ;

• Do we need to take the natural join of two big


relations just to get a relation with one tuple?
• Can we rewrite the query without using a join?
Subquery Example

• Find the name of the professor who teaches “CS


4604.”
SELECT Name
FROM Professors
WHERE PID =
(SELECT ProfessorPID
FROM Teach
WHERE (Number = 4604) AND (DeptName = ’CS’)
);

– When using =, the subquery must return a single tuple


Conditions Involving Relations
• SQL includes a number of operators that apply to a
relation and produce a boolean result. These
operators are very useful to apply on results of sub-
queries.
• Let R be a relation and t be a tuple with the same set
of attributes.
– EXISTS R is true if and only if R contains at least one
tuple.
– t IN R is true if and only if t equals a tuple in R.
– t > ALL R is true if and only if R is unary (has one
attribute) and t is greater than every value in R.
• Can use any of the other five comparison operators.
• If we use <>, R need not be unary.
– t > ANY R (which is unary) is true if and only if t is greater
than at least one value in R.
• We can use NOT to negate EXISTS, ALL, and ANY.
Subqueries Using
Conditions
• Find the departments of the courses taken by the
student with name ‘Suri’.

SELECT DeptName
FROM Take
WHERE StudentPID IN
( SELECT PID
FROM Students
WHERE (Name = ‘Suri’)
);
Subquery Example
• Show all customers who have
placed an order
• SELECT CUSTOMER_NAME FROM
CUSTOMER_T
WHERE CUSTOMER_ID IN
(SELECT DISTINCT CUSTOMER_ID FROM
ORDER_T);

Subquery is embedded in
parentheses. In this case it
returns a list that will be
used in the WHERE clause
of the outer query
14
Correlated vs Uncorrelated
• The previous subqueries did not depend on anything
outside the subquery. These are called uncorrelated and
can run by its own.
• In case of correlated subquery inner query depends on
outer query. Outer query executed before inner query or
subquery while in case of uncorrelated subquery inner
query executes before outer query.
• Correlated Sub-queries are slower than uncorrelated
subquery and should be avoided in favor of sql joins.
• Common example of correlated subquery is using exits and
not exists keyword while uncorrelated query mostly use IN
or NOT IN keywords.
Correlated Subquery
Example
• Show all orders that include furniture finished
in natural ash
The EXISTS operator will return a
TRUE value if the subquery resulted
in a non-empty set, otherwise it
returns a FALSE
SELECT DISTINCT ORDER_ID FROM ORDER_LINE_T
WHERE EXISTS
(SELECT * FROM PRODUCT_T
WHERE PRODUCT_ID = ORDER_LINE_T.PRODUCT_ID
AND PRODUCT_FINISH = ‘Natural ash’);

The subquery is testing for a value


that comes from the outer query
16
Subquery refers to outer-
query data, so executes once
for each row of outer query

17
Another Subquery Example

• Show all products whose price is higher


than the average

SELECT PRODUCT_DESCRIPTION, STANDARD_PRICE,


AVGPRICE
FROM
(SELECT AVG(STANDARD_PRICE) AVGPRICE FROM
PRODUCT_T), PRODUCT_T
WHERE STANDARD_PRICE > AVG_PRICE;

The WHERE clause normally cannot include aggregate functions, but


because the aggregate is performed in the subquery its result can be
used in the outer query’s WHERE clause
Multiple-Row Subquery in a
HAVING Clause
Nested Subqueries

• Maximum of 255 subqueries if


nested in the WHERE clause

• No limit if nested in the FROM clause

• Innermost subquery is resolved first,


then the next level, etc.
Nested Subquery
• Innermost is resolved first (3), then the second
level (2), then the outer query (1)
Nested Subquery Example
• Let us find different ways of writing the query “Find the
names of Professors who have taught the student whose
first name is ’Suri’.”
• The old way:
SELECT Professors.Name
FROM Professors, Take, Teach, Students
WHERE (Professors.PID = Teach.ProfessorPID)
AND (Teach.CourseNumber = Take.CourseNumber)
AND (Teach.DeptName = Take.DeptName)
AND (Take.StudentPID = Student.PID)
AND (Student.Name = ’Suri %’);
“Find the names of (Professors who have taught
(courses taken by (student with first name
’Suri’))).”

SELECT Name
FROM Professors
WHERE PID IN
(SELECT ProfessorPID
FROM Teach
WHERE (Number, DeptName) IN
( SELECT Number, DeptName
FROM TakeWHERE StudentPID IN
(SELECT PID
FROM Students
WHERE Name = ’Suri %’)
)
);
UNION Query Example
Triggers (Active database)
• Trigger: A procedure that starts automatically if
specified changes occur to the DBMS

• Three parts:
– Event (activates the trigger)
– Condition (tests whether the triggers should
run) [Optional]
– Action (what happens if the trigger runs)

• Semantics:
– When event occurs, and condition is satisfied,
the action is performed.
Triggers –
Event,Condition,Action
• Events could be :
BEFORE|AFTER INSERT|UPDATE|DELETE
ON <tableName>
e.g.: BEFORE INSERT ON Professor

• Condition is SQL expression or even an SQL


query (query with non-empty result means
TRUE)

• Action can be many different choices :


– SQL statements , body of PSM, and even
DDL and transaction-oriented statements like
“commit”.
Example Trigger

Assume our DB has a relation schema :

Professor (pNum, pName, salary)

We want to write a trigger that :

Ensures that any new professor inserted


has salary >= 60000
Example Trigger
CREATE TRIGGER minSalary BEFORE INSERT ON Professor

for what context ?

BEGIN

check for violation here ?

END;
Example Trigger
CREATE TRIGGER minSalary BEFORE INSERT ON Professor

FOR EACH ROW

BEGIN

Violation of Minimum Professor Salary?

END;
Example Trigger
CREATE TRIGGER minSalary BEFORE INSERT ON Professor

FOR EACH ROW

BEGIN

IF (:new.salary < 60000)


THEN RAISE_APPLICATION_ERROR (-20004,
‘Violation of Minimum Professor Salary’);
END IF;

END;
Example trigger
CREATE TRIGGER minSalary BEFORE INSERT ON Professor
FOR EACH ROW

DECLARE temp int; -- dummy variable not needed

BEGIN
IF (:new.salary < 60000)
THEN RAISE_APPLICATION_ERROR (-20004,
‘Violation of Minimum Professor Salary’);
END IF;

temp := 10; -- to illustrate declared variables

END;
Details of Trigger Example
• BEFORE INSERT ON Professor
– This trigger is checked before the tuple is inserted
• FOR EACH ROW
– specifies that trigger is performed for each row
inserted
• :new
– refers to the new tuple inserted
• If (:new.salary < 60000)
– then an application error is raised and hence the
row is not inserted; otherwise the row is inserted.
• Use error code: -20004;
– this is in the valid range
Example Trigger Using
Condition
CREATE TRIGGER minSalary BEFORE INSERT ON
Professor
FOR EACH ROW
WHEN (new.salary < 60000)
BEGIN
RAISE_APPLICATION_ERROR (-20004,
‘Violation of Minimum Professor Salary’);
END;

• Conditions can refer to old/new values of tuples modified


by the statement activating the trigger.
Triggers: REFERENCING
CREATE TRIGGER minSalary BEFORE INSERT ON
Professor

REFERENCING NEW as newTuple

FOR EACH ROW

WHEN (newTuple.salary < 60000)

BEGIN
RAISE_APPLICATION_ERROR (-20004,
‘Violation of Minimum Professor Salary’);
END;
Example Trigger
CREATE TRIGGER minSalary
BEFORE UPDATE ON Professor
REFERENCING OLD AS oldTuple NEW as newTuple
FOR EACH ROW
WHEN (newTuple.salary < oldTuple.salary)
BEGIN
RAISE_APPLICATION_ERROR (-20004, ‘Salary
Decreasing !!’);
END;
.

• Ensure that salary does not decrease


Another Trigger Example

CREATE TRIGGER youngSailorUpdate


AFTER INSERT ON SAILORS
REFERENCING NEW TABLE AS NewSailors
FOR EACH STATEMENT
INSERT INTO YoungSailors(sid, name, age,
rating)
SELECT sid, name, age, rating
FROM NewSailors N
WHERE N.age <= 18
Row vs Statement Level
Trigger
• Row level: activated once per modified tuple
• Statement level: activate once per SQL
statement. Remember that one SQL
modification statement can affect many
tuples
• Row level triggers can access new data,
statement level triggers cannot always do
that (depends on DBMS).
• Statement level triggers will be more efficient
if we do not need to make row-specific
decisions
Row vs Statement Level
Trigger
• Example: Consider a relation
schema

Account (num, amount)

Where we will allow creation of new


accounts only during normal
business hours.
Example: Statement level
trigger
CREATE TRIGGER MYTRIG1
BEFORE INSERT ON Account
FOR EACH STATEMENT --- is default
BEGIN
IF (TO_CHAR(SYSDATE,’dy’) IN (‘sat’,’sun’))
OR
(TO_CHAR(SYSDATE,’hh24:mi’) NOT BETWEEN
’08:00’ AND ’17:00’)
THEN
RAISE_APPLICATION_ERROR(-20500,’Cannot
create new account now !!’);
END IF;
END;
Combining multiple events
into one trigger
CREATE TRIGGER salaryRestrictions
AFTER INSERT OR UPDATE ON Professor
FOR EACH ROW
BEGIN
IF (INSERTING AND :new.salary < 60000)
THEN RAISE_APPLICATION_ERROR (-20004,
'below min salary'); END IF;
IF (UPDATING AND :new.salary <
:old.salary) THEN
RAISE_APPLICATION_ERROR (-20004, ‘Salary
Decreasing !!'); END IF;
END;
Summary : Trigger Syntax
CREATE TRIGGER <triggerName>
BEFORE|AFTER INSERT|DELETE|UPDATE
[OF <columnList>] ON <tableName>|<viewName>
[REFERENCING [OLD AS <oldName>] [NEW AS
<newName>]]
[FOR EACH ROW] (default is “FOR EACH STATEMENT”)
[WHEN (<condition>)]
SQL Views
• A SQL view is a virtual table that is constructed
from other tables or views
• A view has no data of its own, but uses data stored
in tables or other views
• Views are created using SQL SELECT statements
• Views are used in other SELECT statements just as
if they were a table
• The SQL statements that create the views may not
contain an ORDER BY clause
• If the results of a query using a view need to be
sorted, the sort order must be provided by the
SELECT statement that processes the view
SQL CREATE VIEW Statement

• The SQL CREATE VIEW statement


is used to create view structures.
CREATE VIEW ViewName AS
{SQL SELECT statement};

Example:
CREATE VIEW EmployeePhoneView AS
SELECT FirstName, LastName,
Phone AS EmployeePhone
FROM EMPLOYEE;
Using an SQL SELECT Statement

• Once the view is created, it can be


used in the FROM clause of
SELECT statements just like a table.
SELECT *
FROM EmployeePhoneView
ORDER BY LastName;
Some Uses for SQL Views

• Hide columns or rows

• Display results of computations

• Hide complicated SQL syntax

• Layer built-in functions


Using SQL Views:
Hide columns or rows I

CREATE VIEW BasicDepartmentDataView AS


SELECT DepartmentName,
Phone AS DepartmentPhone
FROM DEPARTMENT;

SELECT * FROM BasicDepartmentDataView


ORDER BY DepartmentName;
Using SQL Views:
Hide columns or rows II

CREATE VIEW MarkingDepartmentProjectView AS


SELECT ProjectID, Name AS ProjectName,
MaxHours, StartDate, EndDate
FROM PROJECT
WHERE Department = 'Marketing';

SELECT * FROM MarkingDepartmentProjectView


ORDER BY ProjectID;
Using SQL Views:
Display results of computations

CREATE VIEW ProjectHoursToDateView AS


SELECT PROJECT.ProjectID,
Name AS ProjectName,
MaxHours AS projectMaxHours,
SUM(HoursWorked) AS
projectHoursWorkedToDate
FROM PROJECT, ASSIGNMENT
WHERE PROJECT.ProjectID =
ASSIGNMENT.ProjectID
GROUP BY PROJECT.ProjectID;
Using SQL Views:
Display results of computations – Results

SELECT * FROM ProjectHoursToDateView


ORDER BY PROJECT.ProjectID;
Using SQL Views:
Hide complicated SQL syntax

CREATE VIEW EmployeeProjectHoursWorkedView AS


SELECT Name, FirstName, LastName,
HoursWorked
FROM EMPLOYEE AS E JOIN ASSIGNMENT AS A
ON E.EmployeeNumber =
A.EmployeeNumber
JOIN PROJECT AS P
ON A.ProjectID = P.ProjectID;
Using SQL Views:
Hide complicated SQL syntax – Results

SELECT * FROM EmployeeProjectHoursWorkedView;


Using SQL Views:
Layering Computations and Built-in Functions
1st SQL Statement
CREATE VIEW ProjectHoursToDateView AS
SELECT PPOJECT.ProjectID, Name AS ProjectName,
MaxHours AS ProjectMaxHours, SUM(HoursWorked) AS
ProjectHoursWorkedToDate
FROM PROJECT, ASSIGNMENT
WHERE PROJECT.ProjectID = ASSIGNMENT.ProjectID
GROUP BY PROJECT.ProjectID;

Layering Computations and Built-in Functions 2nd SQL Statement

CREATE VIEW ProjectsOverAllotedMaxHoursView AS


SELECT ProjectID, ProjectName,
ProjectMaxHours,
ProjectHoursWorkedToDate
FROM ProjectHoursToDateView
WHERE ProjectHoursWorkedToDate >
ProjectMaxHours;
Using SQL Views:
Layering Computations and Built-in Functions
Results
SELECT ProjectID, ProjectName,
ProjectMaxHours,
ProjectHoursWorkedToDate,
(ProjectHoursWorkedToDate
- ProjectMaxHours)
AS HoursOverMaxAllocated
FROM ProjectsOverAllotedMaxHoursView
ORDER BY ProjectID;

You might also like