Data Celko
Data Celko
Data Celko
Program
in SQL
By
Joe Celko
Copyright 2007
Joe Celko - Articles
z Algebra is important!
z Procedural approach:
parse the string left to right until you hit a comma
slice off the substring to the left of the comma
cast that substring as an integer
parse past comma
loop and lop until the string is empty
Sequence -4
z Non-procedural approach
find all the commas at once
find all the digits bracketed by pairs of sequential
commas, adding one on each end
convert that set of substrings into integers as a set
z SELECT I1.keycol,
CAST (SUBSTRING (, || instring || , FROM S1.seq +1
FOR S2.seq - S1.seq -1) AS INTEGER)
FROM InputStrings AS I1,
Sequence AS S1, Sequence AS S2
WHERE SUBSTRING (, || instring || , FROM S1.seq FOR 1)
= ,
AND SUBSTRING (, || instring || , FROM S2.seq FOR 1)
= ,
AND S1.seq < S2.seq
AND S2.seq = (SELECT MIN(S3.seq)
FROM Sequence AS S3
WHERE S1.seq < S3.seq);
Subsets - 1
6
6
7
6 6
7 9 8 7
Top(n) Values
z Procedural approach:
Sort the file in descending order
return the top (n) of them with a loop
z Problems: the spec is bad
How do you handle multiple copies of a value?
How do you handle exactly (n) values?
How do you handle less than (n) values?
Top (n) Values - 3
z Subset approach:
Decide if ties count or not; this is the pure set
model versus SQLs multi-set model
SELECT *
FROM (SELECT Foo.*,
ROW_NUMBER()
OVER(ORDER BY foo_key) AS row_nbr
FROM Foo) AS F
WHERE row_nbr < (:n);
z SELECT Pilot
FROM PilotSkills AS PS1, Hanger AS H1
WHERE PS1.plane = H1.plane
GROUP BY PS1.pilot
HAVING COUNT(PS1.plane)
= (SELECT COUNT(*) FROM Hanger)
Relational Division - 4
z SELECT Pilot
FROM PilotSkills AS P1
WHERE NOT EXISTS
(SELECT plane FROM Hanger
EXCEPT
SELECT plane FROM PilotSkills AS P2
WHERE P1.pilot = P2.pilot);
Trees in SQL
Root
A0 B0
A1 A2
Tree as Nested Sets
root
A0 B0
A1 A2
Graph as Table
node parent
==========
Root NULL
A0 Root
A1 A0
A2 A0
B0 Root
Graph with Traversal
Root
left = 1
right =10
A0 B0
left = 2 left = 8
right = 7 right = 9
A1 A2
left = 3 left = 5
right = 4 right = 6
Nested Sets with Numbers
1 2 3 4 5 6 7 8 9 10
Root A0 B0
A1 A2
Nested Sets as Numbers
z SELECT Super.*
FROM Tree AS T1, Tree AS Supers
WHERE node = X
AND T1.lft BETWEEN Supers.lft AND
Supers.rgt;
Find Subordinates of X
z SELECT Subordinates.*
FROM Tree AS T1,
Tree AS Subordinates
WHERE T1.node = X
AND Subordinates.lft BETWEEN
T1.lft AND T1.rgt;
Totals by Level in Tree
z SELECT department,
SUM(CASE WHEN sex = m
THEN 1 ELSE 0 END) AS men,
SUM(CASE WHEN sex = f
THEN 1 ELSE 0 END) AS women
FROM Personnel
GROUP BY department;
CASE Expressions -1
z First attempt:
BEGIN
UPDATE Books SET price = price *1.10 WHERE price <= $25.00;
UPDATE Books SET price = price *0.85 WHERE price > $25.00;
END;