Example: Ancestors
ParentOf(parent,child)
Example: Company hierarchy
Employee(ID,salary), Manager(mgrID,empID), Project(name,mgrID)
Example: Airline flights
Flight(origin,destination,airline,cost)
WITH statement
WITH R1 AS (query),
R2 AS (query),
...,
Rn AS (query)
<query involving R1, R2,...,Rn and other relations>
Idea:
R1, R2,...,Rn into temporary relations
R1,...,Rn and other relations
R1, R2,...,Rn
WITH R1(A1, A2, ..., Am) AS (query), ...Example:
WITH Berk AS (SELECT ID, date FROM Apply WHERE location = "Berkeley"),
SC AS (SELECT ID, date FROM Apply WHERE location = "SC")
SELECT Berk.ID, Berk.date AS Bdate, SC.date AS SCdate
FROM Berk, SC
WHERE Berk.ID = SC.ID
WITH statement looks like "temporary view definitions" for syntactic
convenience.
RECURSIVE
UNION of base case + recursion
ParentOf(parent,child)
WITH RECURSIVE Ancestor(anc,desc) AS
( (SELECT parent as anc, child as desc FROM ParentOf)
UNION
(SELECT Ancestor.anc, ParentOf.child as desc
FROM Ancestor, ParentOf
WHERE Ancestor.desc = ParentOf.parent) )
SELECT anc FROM Ancestor WHERE desc = "Mary"
(show procedural evaluation with fixpoint)
Example: Total salary cost of Project "X"
WITH RECURSIVE Superior AS
( (SELECT * from Manager)
UNION
(SELECT S.mgrID, M.empID
FROM Superior S, Manager M
WHERE S.empID = M.mgrID) )
SELECT sum(salary)
FROM Employee
WHERE ID IN
((SELECT mgrID FROM Project WHERE name = 'X')
UNION
(SELECT empID FROM Project, Superior
WHERE Project.name = 'X' AND Project.mgrID = Superior.mgrID))
(show example data and computation)
Alternative formulation, more specific to this query:
WITH RECURSIVE Xemps(ID) AS
( (SELECT mgrID AS ID FROM Project WHERE name = "X")
UNION
(SELECT empID AS ID
FROM Manager
WHERE mgrID IN (Select ID FROM Xemps)) )
SELECT sum(salary)
FROM Employee
WHERE ID IN (SELECT ID FROM Xemps)
(show computation)
Flights example left as exercise
FROM
has at most one reference to a recursively-defined relation.
Example: Nonlinear version of Ancestor:
WITH RECURSIVE Ancestor(anc,desc) AS
( (SELECT parent as anc, child as desc FROM ParentOf)
UNION
(SELECT A1.anc, A2.desc
FROM Ancestor A1, Ancestor A2
WHERE A1.desc = A2.anc) )
SELECT anc FROM Ancestor WHERE desc = "Mary"
Sales(ID,amt)
WITH RECURSIVE Banquet(ID) AS
(SELECT ID
FROM Sales
WHERE amt > 10,000
AND ID NOT IN (SELECT ID FROM Bonus)),
RECURSIVE Bonus(ID) AS
(SELECT ID
FROM Sales
WHERE amt > 20,000
AND ID NOT IN (SELECT ID FROM Banquet))
<any query>
Question: What's wrong?
NOT IN)
Example: Given relation Q(x)
P(x) = Q(x) UNION R(x) R(x) = P(x) UNION sum(P(x))Question: What happens?