CSE544: SQL: Monday 3/27 and Wednesday 3/29, 2006
CSE544: SQL: Monday 3/27 and Wednesday 3/29, 2006
Tables in SQL
Product
Tuples or rows
Tables Explained
The schema of a table is the table name and
its attributes:
Product(PName, Price, Category, Manfacturer)
SELECT <attributes>
FROM <one or more relations>
WHERE <conditions>
Simple SQL Query
Product PName Price Category Manufacturer
Gizmo $19.99 Gadgets GizmoWorks
Powergizmo $29.99 Gadgets GizmoWorks
SingleTouch $149.99 Photography Canon
MultiTouch $203.99 Household Hitachi
SELECT *
FROM Product
WHERE category=Gadgets
Output Schema
Details
Case insensitive:
Same: SELECT Select select
Same: Product product
Different: Seattle seattle
Constants:
abc - yes
abc - no
The LIKE operator
SELECT *
FROM Products
WHERE PName LIKE %gizmo%
Compare to:
Category
Gadgets
SELECT category Gadgets
FROM Product Photography
Household
Ordering the Results
SELECT pname, price, manufacturer
FROM Product
WHERE category=gizmo AND price > 50
ORDER BY price, pname
Ties are broken by the second attribute on the ORDER BY list, etc.
GizmoWorks 25 USA
Key
Canon 65 Japan
Hitachi 15 Japan
Product
PName Price Category Manufacturer
Foreign
Gizmo $19.99 Gadgets GizmoWorks
key
Powergizmo $29.99 Gadgets GizmoWorks
SingleTouch $149.99 Photography Canon
MultiTouch $203.99 Household Hitachi
Joins
Product (pname, price, category, manufacturer)
Company (cname, stockPrice, country)
SELECT cname
FROM
WHERE
A Subtlety about Joins
Product (pname, price, category, manufacturer)
Company (cname, stockPrice, country)
SELECT Country
FROM Product, Company
WHERE Manufacturer=CName AND Category=Gadgets
Unexpected duplicates
A Subtlety about Joins
Product Company
SELECT Country
FROM Product, Company
WHERE Manufacturer=CName AND Category=Gadgets
Country
What is ??
the problem ? ??
Whats the
solution ?
Tuple Variables
Person(pname, address, worksfor)
Company(cname, address)
Which
SELECT DISTINCT pname, address address ?
FROM Person, Company
WHERE worksfor = cname
SELECT DISTINCT Person.pname, Company.address
FROM Person, Company
WHERE Person.worksfor = Company.cname
SELECT DISTINCT x.pname, y.address
FROM Person AS x, Company AS y
WHERE x.worksfor = y.cname
Meaning (Semantics) of SQL
Queries
SELECT a1, a2, , ak
FROM R1 AS x1, R2 AS x2, , Rn AS xn
WHERE Conditions
Answer = {}
for x1 in R1 do
for x2 in R2 do
..
for xn in Rn do
if Conditions
then Answer = Answer {(a1,,ak)}
return Answer
An Unintuitive Query
SELECT Company.city
FROM Company, Product, Purchase
WHERE Company.name= Product.maker
AND Product.pname = Purchase.product
AND Purchase.buyer = Joe Blow
Beware of duplicates !
Removing Duplicates
SELECT DISTINCT Company.city
FROM Company
WHERE Company.name IN
(SELECT Product.maker
FROM Purchase , Product
WHERE Product.pname=Purchase.product
AND Purchase .buyer = Joe Blow);
SELECT name
FROM Product
WHERE price > ALL (SELECT price
FROM Purchase
WHERE maker=Gizmo-Works)
Question for Database Fans
and their Friends
Can we express this query as a single
SELECT-FROM-WHERE query, without
subqueries ?
Question for Database Fans
and their Friends
Answer: all SFW queries are
monotone (figure out what this means).
A query with ALL is not monotone
Correlated Queries
Movie (title, year, director, length)
Find movies whose title appears more than once.
correlation
Note (1) scope of variables (2) this can still be expressed as single SFW
Complex Correlated Query
Product ( pname, price, category, maker, year)
Find products (and their manufacturers) that are more expensive
than all products made by the same manufacturer before 1972
We probably want:
SELECT product,
sum(price * quantity) AS SumSales
max(quantity) AS MaxQuantity
FROM Purchase
GROUP BY product
HAVING Clause
Same query, except that we consider only products that had
at least 100 buyers.
2. Quantifiers
Find all companies that make some products with price < 100
Existential: easy !
2. Quantifiers
Product ( pname, price, company)
Company( cname, city)
Find all companies that make only products with price < 100
same as:
Find all companies s.t. all of their products have price < 100
Universal: hard !
2. Quantifiers
1. Find the other companies: i.e. s.t. some product 100
SELECT DISTINCT Company.cname
FROM Company
WHERE Company.cname IN (SELECT Product.company
FROM Product
WHERE Produc.price >= 100
2. Find all companies s.t. all their products have price < 100
SELECT DISTINCT Company.cname
FROM Company
WHERE Company.cname NOT IN (SELECT Product.company
FROM Product
WHERE Produc.price >= 100
3. Group-by v.s. Nested Query
Author(login,name)
Wrote(login,url)
Find authors who wrote 10 documents: This is
Attempt 1: with nested queries SQL by
a novice
SELECT DISTINCT Author.name
FROM Author
WHERE count(SELECT Wrote.url
FROM Wrote
WHERE Author.login=Wrote.login)
> 10
3. Group-by v.s. Nested Query
Find all authors who wrote at least 10
documents:
Attempt 2: SQL style (with GROUP BY)
SELECT Author.name This is
FROM Author, Wrote SQL by
WHERE Author.login=Wrote.login an expert
GROUP BY Author.name
HAVING count(wrote.url) > 10
Store(sid, sname)
Product(pid, pname, price, sid)
Find all stores that sell only products with price > 100
same as:
Find all stores s.t. all their products have price > 100)
SELECT Store.name
FROM Store, Product
WHERE Store.sid = Product.sid Why both ?
GROUP BY Store.sid, Store.name
HAVING 100 < min(Product.price)
SELECT Store.name
FROM Store
Almost equivalent WHERE
100 < ALL (SELECT Product.price
FROM product
WHERE Store.sid = Product.sid)
SELECT Store.name
FROM Store
WHERE Store.sid NOT IN
(SELECT Product.sid
FROM Product
WHERE Product.price <= 100)
Two Examples
Store(sid, sname)
Product(pid, pname, price, sid)
Better:
SELECT Store.sname, x.pname
FROM Store, Product x
But may WHERE Store.sid = x.sid and
return x.price >=
multiple ALL (SELECT y.price
product names FROM Product y
per store WHERE Store.sid = y.sid)
Two Examples
Finally, choose some pid arbitrarily, if there are many
with highest price:
SELECT * E.g.
FROM Person age=20
WHERE (age < 25) AND heigth=NULL
weight=200
(height > 6 OR weight > 190)
Rule in SQL: include only tuples that yield TRUE
Null Values
Unexpected behavior:
SELECT *
FROM Person
WHERE age < 25 OR age >= 25
SELECT *
FROM Person
WHERE age < 25 OR age >= 25 OR age IS NULL
Name Store
Gizmo Wiz
Camera Ritz
Camera Wiz
OneClick NULL
Application
Compute, for each product, the total number of sales in September
Product(name, category)
Purchase(prodName, month, store)
Whats wrong ?
Application
Compute, for each product, the total number of sales in September
Product(name, category)
Purchase(prodName, month, store)
camera - -
Insertion: an Example
INSERT INTO Product(name, listPrice)
camera 200 -
UPDATE PRODUCT
SET price = price/2
WHERE Product.name IN
(SELECT product
FROM Purchase
WHERE Date =Oct, 25, 1999);