Matthew P. Johnson, OCL3, CISDD CUNY, June 20051 OCL3 Oracle 10g: SQL & PL/SQL Session #4 Matthew P....
-
date post
20-Dec-2015 -
Category
Documents
-
view
225 -
download
0
Transcript of Matthew P. Johnson, OCL3, CISDD CUNY, June 20051 OCL3 Oracle 10g: SQL & PL/SQL Session #4 Matthew P....
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
1
OCL3 Oracle 10g:SQL & PL/SQLSession #4
Matthew P. Johnson
CISDD, CUNY
June, 2005
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
3
Review Examples from sqlzoo.net
SELECT LFROM R1, …, Rn
WHERE C
SELECT LFROM R1, …, Rn
WHERE C
L(C(R1 x … Rn)L(C(R1 x … Rn)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
4
SQL e.g. Acc(name,ssn,balance) Q: Who has the largest balance?
Conceptually:
name(Acc) - a2.name(a2.bal < Acc.bal(Acc x a2(Acc)))
In SQL?
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
5
New topic: Subqueries Powerful feature of SQL: one clause can
contain other SQL queries Anywhere where a value or relation is allowed
Several ways: Selection single constant (scalar) in SELECT Selection single constant (scalar) in WHERE Selection relation in WHERE Selection relation in FROM
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
6
Subquery motivation Consider standard multi-table example:
Purchase(prodname, buyerssn, etc.) Person(name, ssn, etc.) What did Christo buy?
As usual, need to AND on equality identifying ssn’s row and buyerssn’s row
SELECT Purchase.prodnameFROM Purchase, PersonWHERE buyerssn = ssn AND name = 'Christo'
SELECT Purchase.prodnameFROM Purchase, PersonWHERE buyerssn = ssn AND name = 'Christo'
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
7
Subquery motivation Purchase(prodname, buyerssn, etc.) Person(name, ssn, etc.) What did Conrad buy?
Natural intuition: Go find Conrad’s ssn Then find purchases
SELECT ssnFROM PersonWHERE name = 'Christo'
SELECT ssnFROM PersonWHERE name = 'Christo'
SELECT Purchase.prodnameFROM PurchaseWHERE buyerssn = Christo’s-ssn
SELECT Purchase.prodnameFROM PurchaseWHERE buyerssn = Christo’s-ssn
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
8
Subqueries Subquery: copy in Conrad’s selection for his ssn:
The subquery returns one value, so the = is valid If it returns more (or fewer), we get a run-time error
SELECT Purchase.prodnameFROM PurchaseWHERE buyerssn = (SELECT ssn FROM Person WHERE name = 'Christo')
SELECT Purchase.prodnameFROM PurchaseWHERE buyerssn = (SELECT ssn FROM Person WHERE name = 'Christo')
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
9
Operators on subqueries Several new operators applied to (unary)
selections:1. IN R
2. EXISTS R
3. UNIQUE R
4. s > ALL R
5. s > ANY R
6. x IN R > is just an example op Each expression can be negated with NOT
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
10
Subqueries with IN Product(name,maker), Person(name,ssn),
Purchase(buyerssn,product) Q: Find companies Martha bought products from Strategy:
1. Find Martha’s ssn2. Find products listed with that ssn as buyer3. Find company names of those products
SELECT DISTINCT Product.makerFROM ProductWHERE Product.name IN (SELECT Purchase.product FROM Purchase WHERE Purchase.buyerssn =
(SELECT ssn FROM Person
WHERE name = 'Martha'))
SELECT DISTINCT Product.makerFROM ProductWHERE Product.name IN (SELECT Purchase.product FROM Purchase WHERE Purchase.buyerssn =
(SELECT ssn FROM Person
WHERE name = 'Martha'))
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
11
Subqueries returning relations Equivalent to:
SELECT DISTINCT Product.makerFROM Product, Purchase, PeopleWHERE Product.name = Purchase.product AND Purchase.buyerssn = ssn AND name = 'Martha'
SELECT DISTINCT Product.makerFROM Product, Purchase, PeopleWHERE Product.name = Purchase.product AND Purchase.buyerssn = ssn AND name = 'Martha'
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
12
FROM subqueries Motivation for another way:
suppose we’re given Martha’s purchases Then could just cross with Products to get product makers
Substitute (named) subquery for Martha’s purchases
SELECT Product.makerFROM Product, (SELECT Purchase.product FROM Purchase WHERE Purchase.buyerssn =
(SELECT ssn FROM Person WHERE name = 'Martha')) Marthas
WHERE Product.name = Marthas.product
SELECT Product.makerFROM Product, (SELECT Purchase.product FROM Purchase WHERE Purchase.buyerssn =
(SELECT ssn FROM Person WHERE name = 'Martha')) Marthas
WHERE Product.name = Marthas.product
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
13
ALL op
Employees(name, job, divid, salary)Find which employees are paid more than all the programmers
SELECT nameFROM EmployeesWHERE salary > ALL (SELECT salary FROM Employees WHERE job='programmer')
SELECT nameFROM EmployeesWHERE salary > ALL (SELECT salary FROM Employees WHERE job='programmer')
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
14
ANY/SOME op
Employees(name, job, divid, salary)Find which employees are paid more than at least one vice president
SELECT nameFROM EmployeesWHERE salary > ANY (SELECT salary FROM Employees WHERE job='VP')
SELECT nameFROM EmployeesWHERE salary > ANY (SELECT salary FROM Employees WHERE job='VP')
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
15
ANY/SOME op
Employees(name, job, divid, salary)Find which employees are paid more than at least one vice president
SELECT nameFROM EmployeesWHERE salary > SOME (SELECT salary FROM Employees WHERE job='VP')
SELECT nameFROM EmployeesWHERE salary > SOME (SELECT salary FROM Employees WHERE job='VP')
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
16
Existential/Universal ConditionsEmployees(name, job, divid, salary)
Division(name, id, head)
Find all divisions with an employee whose salary is > 100000
Existential: easy!
SELECT DISTINCT Division.nameFROM Employees, DivisionWHERE salary > 100000 AND divid=id
SELECT DISTINCT Division.nameFROM Employees, DivisionWHERE salary > 100000 AND divid=id
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
17
Existential/Universal ConditionsEmployees(name, job, divid, salary)
Division(name, id, head)
Find all divisions in which everyone makes > 100000
Universal: hard!
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
18
Existential/universal with IN
2. Select the divisions we didn’t find
1. Find the other divisions: in which someone makes <= 100000
SELECT nameFROM DivisionWHERE id IN (SELECT divid FROM Employees WHERE salary <= 100000
SELECT nameFROM DivisionWHERE id IN (SELECT divid FROM Employees WHERE salary <= 100000
SELECT nameFROM DivisionWHERE id NOT IN (SELECT divid FROM Employees WHERE salary <= 100000
SELECT nameFROM DivisionWHERE id NOT IN (SELECT divid FROM Employees WHERE salary <= 100000
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
19
Acc(name,bal,type…) Q: Who has the largest balance?
Can we do this with subqueries?
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
20
Last time: Acc(name,bal,type,…) Q: Find holder of largest account
SELECT nameFROM AccWHERE bal >= ALL (SELECT bal FROM Acc)
SELECT nameFROM AccWHERE bal >= ALL (SELECT bal FROM Acc)
Correlated Queries
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
21
Correlated Queries So far, subquery executed once;
result used for higher query More complicated: correlated queries
“[T]he subquery… [is] evaluated many times, once for each assignment of a value to some term in the subquery that comes from a tuple variable outside the subquery” (Ullman, p286).
Q: What does this mean? A: That subqueries refer to vars from outer queries
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
22
Last time: Acc(name,bal,type,…) Q2: Find holder of largest account of each type
SELECT name, typeFROM AccWHERE bal >= ALL (SELECT bal FROM Acc WHERE type=type)
SELECT name, typeFROM AccWHERE bal >= ALL (SELECT bal FROM Acc WHERE type=type)
Correlated Queries
correlation
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
23
Last time: Acc(name,bal,type,…) Q2: Find holder of largest account of each type
Note:1. scope of variables
2. this can still be expressed as single SFW
SELECT name, typeFROM Acc a1WHERE bal >= ALL (SELECT bal FROM Acc WHERE type=a1.type)
SELECT name, typeFROM Acc a1WHERE bal >= ALL (SELECT bal FROM Acc WHERE type=a1.type)
Correlated Queries
correlation
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
24
EXCEPT and INTERSECT
(SELECT R.A, R.B FROM R) INTERSECT(SELECT S.A, S.B FROM S)
(SELECT R.A, R.B FROM R) INTERSECT(SELECT S.A, S.B FROM S)
(SELECT R.A, R.B FROM R) EXCEPT(SELECT S.A, S.B FROM S)
(SELECT R.A, R.B FROM R) EXCEPT(SELECT S.A, S.B FROM S)
SELECT R.A, R.BFROM RWHERE EXISTS(SELECT * FROM S WHERE R.A=S.A and R.B=S.B)
SELECT R.A, R.BFROM RWHERE EXISTS(SELECT * FROM S WHERE R.A=S.A and R.B=S.B)
SELECT R.A, R.BFROM RWHERE NOT EXISTS(SELECT * FROM S WHERE R.A=S.A and R.B=S.B)
SELECT R.A, R.BFROM RWHERE NOT EXISTS(SELECT * FROM S WHERE R.A=S.A and R.B=S.B)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
25
More on Set-Comparison Operators We’ve already seen IN R, NOT IN R. Can also use EXISTS R, NOT EXISTS R Also available: op ANY R, op ALL R Find sailors whose rating is greater than that
of some sailor called Alberto: , , , , ,
SELECT R.SIDFROM Reserves RWHERE R.rating > ANY (SELECT R2.rating FROM Reserves R2 WHERE R2.sname=‘Alberto’)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
26
Extended e.g. Scenario:
1. Purchase(pid, seller-ssn, buyer-ssn, etc.)
2. Person(ssn, name, etc.)
3. Product(pid, name, etc.)
Q: Who (give names) bought gizmos from Dick?
Where to start? Purchase uses pid, ssn, so must get them…
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
27
Last time: Complex RA Expressions Scenario:
1. Purchase(pid, seller-ssn, buyer-ssn, etc.)
2. Person(ssn, name, etc.)
3. Product(pid, name, etc.)
Q: Who (give names) bought gizmos from Dick?
Where to start? Purchase uses pid, ssn, so must get them…
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
28
Complex RA Expressions
Person Purchase Person Product
name='Dick' name='Gizmo'
pid ssn
seller-ssn=ssn
pid=pid
buyer-ssn=Person.ssn
name
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
29
Translation to SQL
We’re converting the tree on the last slide into SQL The result of the query should be the names indicated above One step at a time, we’ll make the query more complete, until
we’ve translated the English-language description to an actual SQL query
We’ll also simplify the query when possible
(the names of the people who bought gadgets from Dick)
(the names of the people who bought gadgets from Dick)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
30
Translation to SQL
Blue type = actual SQL Black italics = description of subquery
Note: the subquery above consists of purchase records, except with the info describing the buyers attached In the results, the column header for name will be 'buyer'
SELECT DISTINCT name buyer FROM
(the info, along with buyer names, for purchases of gadgets sold by Dick)
SELECT DISTINCT name buyer FROM
(the info, along with buyer names, for purchases of gadgets sold by Dick)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
31
Translation to SQL
Note: the subquery in this version is being given the name P2 We’re pairing our rows from Person with rows from P2
SELECT DISTINCT name buyer FROM
(SELECT *FROM Person, (the purchases of gadgets from Dick) P2
WHERE Person.ssn = P2.buyer-ssn)
SELECT DISTINCT name buyer FROM
(SELECT *FROM Person, (the purchases of gadgets from Dick) P2
WHERE Person.ssn = P2.buyer-ssn)
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
32
Translation to SQL
We simplified by combining the two SELECTs
SELECT DISTINCT name buyer
FROM Person, (the purchases of gadgets from Dick) P2
WHERE Person.ssn = P2.buyer-ssn
SELECT DISTINCT name buyer
FROM Person, (the purchases of gadgets from Dick) P2
WHERE Person.ssn = P2.buyer-ssn
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
33
Translation to SQL
P2 is still the name of the subquery It’s just been filled in with a query that contains two
subqueries Outer parentheses are bolded for clarity
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (Dick’s ssn)
AND pid = (the id of gadget)) P2
WHERE Person.ssn = P2.buyer-ssn
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (Dick’s ssn)
AND pid = (the id of gadget)) P2
WHERE Person.ssn = P2.buyer-ssn
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
34
Translation to SQL
Now the subquery to find Dick’s ssn is filled in
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (SELECT ssn FROM Person WHERE name='Dick') AND pid = (the id of gadget)) P2
WHERE Person.ssn = P2.buyer-ssn
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (SELECT ssn FROM Person WHERE name='Dick') AND pid = (the id of gadget)) P2
WHERE Person.ssn = P2.buyer-ssn
Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
35
Translation to SQL
And now the subquery to find Gadget’s product id is filled in, too Note: the SQL simplified by using subqueries
Not used in relational algebra
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (SELECT ssn FROM Person WHERE name='Dick') AND pid = (SELECT pid FROM Product WHERE name='Gadget')) P2WHERE Person.ssn = P2.buyer-ssn
SELECT DISTINCT name buyer
FROM Person, (SELECT * FROM Purchases WHERE seller-ssn = (SELECT ssn FROM Person WHERE name='Dick') AND pid = (SELECT pid FROM Product WHERE name='Gadget')) P2WHERE Person.ssn = P2.buyer-ssn