Matthew P. Johnson, OCL3, CISDD CUNY, June 20051 OCL3 Oracle 10g: SQL & PL/SQL Session #4 Matthew P....

35
Matthew P. Johnson, OCL3, CISDD CUNY, J une 2005 1 OCL3 Oracle 10g: SQL & PL/SQL Session #4 Matthew P. Johnson CISDD, CUNY June, 2005
  • 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

2

Agenda Go over labs 1 and 2 More SQL Lab 4

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