About

Each lab gave us a dataset split across several tables and a list of "information needs" to answer with a single SQL query each. The rule was that a query had to use the names given in the question (like a campus name or a customer's name) and join the tables to get there, instead of looking up an ID by hand and pasting it in. I stuck to what we covered in class: filtering and sorting, multi-table joins, aggregation with GROUP BY and HAVING, and nested subqueries. Below each query is the actual output.

The Bakery Dataset

One month (October 2007) of sales from a small bakery that sells to known customers. A receipt is one purchase, and each receipt lists one to five items.

  • customers (CId, LastName, FirstName)
  • goods (GId, Flavor, Food, Price)
  • receipts (RNumber, SaleDate, Customer → customers)
  • items (Receipt → receipts, Ordinal, Item → goods)

Download BAKERY-queries.sql ↓

Selecting & Joining Tables

Q1. Find all Chocolate-flavored products that cost less than $5. Report the product name (Flavor, Food) and price, cheapest first.

SELECT Flavor, Food, Price
FROM goods
WHERE Flavor = 'Chocolate' AND Price < 5
ORDER BY Price;
FlavorFoodPrice
ChocolateMeringue1.25
ChocolateCroissant1.75
ChocolateEclair3.25
ChocolateTart3.75

4 rows

Q2. Find all purchases made by JULIET LOGAN in October of 2007. Report the receipt number and the date, in date order.

SELECT r.RNumber, r.SaleDate
FROM receipts r, customers c
WHERE r.Customer = c.CId
  AND c.FirstName = 'JULIET' AND c.LastName = 'LOGAN'
  AND r.SaleDate BETWEEN '2007-10-01' AND '2007-10-31'
ORDER BY r.SaleDate;
RNumberSaleDate
662272007-10-10
815172007-10-10
445902007-10-12
858812007-10-13
722072007-10-15
860852007-10-16
376362007-10-20
450622007-10-23

11 rows (showing first 8)

Q3. Find every customer who bought a Gongolais Cookie in October of 2007. Report last and first name, no duplicates, sorted by last name.

SELECT DISTINCT c.LastName, c.FirstName
FROM customers c, receipts r, items i, goods g
WHERE c.CId = r.Customer
  AND r.RNumber = i.Receipt
  AND i.Item = g.GId
  AND g.Flavor = 'Gongolais' AND g.Food = 'Cookie'
  AND r.SaleDate BETWEEN '2007-10-01' AND '2007-10-31'
ORDER BY c.LastName;
LastNameFirstName
ARZTTERRELL
CALLENDARDAVID
DUNLOWOSVALDO
HAFFERKAMPCUC
HELINGRUPERT
STADICKMIGDALIA
TOUSSANDSHARRON

7 rows

Q4. List all products bought on October 18, 2007 that cost more than $5, along with who bought them. Sort by price, most expensive first.

SELECT g.Flavor, g.Food, g.Price, c.FirstName, c.LastName
FROM goods g
  JOIN items i ON i.Item = g.GId
  JOIN receipts r ON r.RNumber = i.Receipt
  JOIN customers c ON c.CId = r.Customer
WHERE r.SaleDate = '2007-10-18' AND g.Price > 5
ORDER BY g.Price DESC, c.LastName;
FlavorFoodPriceFirstNameLastName
TruffleCake15.95TRAVISESPOSITA
LemonCake8.95TRAVISESPOSITA
ApplePie5.25CUCHAFFERKAMP

3 rows

Aggregation (GROUP BY / HAVING)

Q5. For each customer, report the number of purchases they made in October of 2007 and the total amount they spent. Biggest spenders first.

SELECT c.LastName, c.FirstName,
       COUNT(DISTINCT r.RNumber) AS Purchases,
       ROUND(SUM(g.Price), 2) AS TotalSpent
FROM customers c, receipts r, items i, goods g
WHERE c.CId = r.Customer
  AND r.RNumber = i.Receipt
  AND i.Item = g.GId
  AND r.SaleDate BETWEEN '2007-10-01' AND '2007-10-31'
GROUP BY c.CId, c.LastName, c.FirstName
ORDER BY TotalSpent DESC;
LastNameFirstNamePurchasesTotalSpent
HELINGRUPERT18206.61
SLINGLANDJOSETTE15190.41
TOUSSANDSHARRON16187.70
LOGANJULIET11163.19
SOPKORAYFORD15147.60
CRUZENARIANE11145.22
ZEMESTEPHEN16137.16
DUKELOWCORETTA8119.92

20 rows (showing first 8)

Q6. For each type of food the bakery sells, report how many different products there are and the lowest, highest and average price. Only include food types with more than 3 products.

SELECT Food, COUNT(*) AS NumProducts,
       MIN(Price) AS Cheapest, MAX(Price) AS MostExpensive,
       ROUND(AVG(Price), 2) AS AvgPrice
FROM goods
GROUP BY Food
HAVING COUNT(*) > 3
ORDER BY AvgPrice DESC;
FoodNumProductsCheapestMostExpensiveAvgPrice
Cake78.9515.9513.03
Tart103.253.753.40
Croissant51.451.751.57
Cookie70.791.251.07

4 rows

Q7. Find the days in October of 2007 when the bakery made more than $100. Report the date, number of receipts and the revenue for that day.

SELECT r.SaleDate, COUNT(DISTINCT r.RNumber) AS Receipts,
       ROUND(SUM(g.Price), 2) AS Revenue
FROM receipts r, items i, goods g
WHERE r.RNumber = i.Receipt
  AND i.Item = g.GId
  AND r.SaleDate BETWEEN '2007-10-01' AND '2007-10-31'
GROUP BY r.SaleDate
HAVING SUM(g.Price) > 100
ORDER BY Revenue DESC;
SaleDateReceiptsRevenue
2007-10-1211169.87
2007-10-048137.79
2007-10-1010131.92
2007-10-169112.97
2007-10-0910112.97
2007-10-195111.78
2007-10-0710104.98

7 rows

Nested Queries

Q8. Find the most popular product (bought the most times overall). Report the product name and how many times it was bought.

SELECT g.Flavor, g.Food, COUNT(*) AS TimesBought
FROM goods g, items i
WHERE g.GId = i.Item
GROUP BY g.GId, g.Flavor, g.Food
HAVING COUNT(*) = (SELECT MAX(cnt)
                   FROM (SELECT COUNT(*) AS cnt
                         FROM items
                         GROUP BY Item) AS counts);
FlavorFoodTimesBought
AppleTart25

1 row

Q9. Find all customers who never bought a cake. Report last and first name, sorted by last name.

SELECT LastName, FirstName
FROM customers
WHERE CId NOT IN (SELECT r.Customer
                  FROM receipts r, items i, goods g
                  WHERE r.RNumber = i.Receipt
                    AND i.Item = g.GId
                    AND g.Food = 'Cake')
ORDER BY LastName;
LastNameFirstName

0 rows

Q10. Find the products that cost more than the average price of products of the same food type. Report name, price and that average.

SELECT g1.Flavor, g1.Food, g1.Price,
       (SELECT ROUND(AVG(g2.Price), 2) FROM goods g2
        WHERE g2.Food = g1.Food) AS AvgForFood
FROM goods g1
WHERE g1.Price > (SELECT AVG(g2.Price)
                  FROM goods g2
                  WHERE g2.Food = g1.Food)
ORDER BY g1.Food, g1.Price DESC;
FlavorFoodPriceAvgForFood
CasinoCake15.9513.03
OperaCake15.9513.03
TruffleCake15.9513.03
NapoleonCake13.4913.03
MarzipanCookie1.251.07
TuileCookie1.251.07
GanacheCookie1.151.07
GongolaisCookie1.151.07

16 rows (showing first 8)

The Wine Dataset

500 single-grape California wines rated by Wine Spectator magazine (2007–2011), with information about each grape and each grape-growing region (appellation).

  • wine (WineId, Grape → grapes, Winery, Appellation → appellations, Name, Vintage, Price, Score, Cases, Drink)
  • grapes (GId, Grape, Color)
  • appellations (No, Appellation, County, State, Area, isAVA)

Download WINE-queries.sql ↓

Selecting & Joining Tables

Q1. Find all wines from the Napa Valley appellation that scored 95 or higher. Report winery, wine name, vintage, score and price, best scores first.

SELECT Winery, Name, Vintage, Score, Price
FROM wine
WHERE Appellation = 'Napa Valley' AND Score >= 95
ORDER BY Score DESC, Price;
WineryNameVintageScorePrice
HourglassCabernet Sauvignon200697135
ChappelletPritchard Hill200796135
DarioushDarius II200796225
NeyersNeyers Ranch - Conn Valley20079548
RameyAnnum20079585
Dancing HaresCabernet Sauvignon20059595
LewisReserve200695125
LewisReserve200795130

8 rows

Q2. Find all white wines made from grapes grown in Sonoma County appellations that scored at least 93. Report grape, winery, appellation, wine name and score.

SELECT w.Grape, w.Winery, w.Appellation, w.Name, w.Score
FROM wine w, grapes g, appellations a
WHERE w.Grape = g.Grape
  AND w.Appellation = a.Appellation
  AND g.Color = 'White'
  AND a.County = 'Sonoma'
  AND w.Score >= 93
ORDER BY w.Score DESC, w.Winery;
GrapeWineryAppellationNameScore
ChardonnayDuMOLSonoma CountyGreen River Isobel95
ChardonnayKistlerSonoma CountyMcCrea Vineyard95
ChardonnayMaybachSonoma CoastEterium B. Thieriot Vineyard95
ChardonnayPeter MichaelSonoma CountyMa Belle-Fille95
ChardonnayThree SticksSonoma ValleyDurell Vineyard95
ChardonnayTorSonoma ValleyDurell Vineyard Wente Clone95
ChardonnayFaillaSonoma CoastEstate Vineyard94
ChardonnayKistlerRussian River ValleyWine Hill Vineyard94

19 rows (showing first 8)

Q3. Find all Pinot Noirs from the Central Coast area from the 2008 or 2009 vintage that cost less than $40. Report winery, name, appellation, price and score, sorted by price.

SELECT w.Winery, w.Name, w.Appellation, w.Price, w.Score
FROM wine w
  JOIN appellations a ON w.Appellation = a.Appellation
WHERE w.Grape = 'Pinot Noir'
  AND a.Area = 'Central Coast'
  AND w.Vintage IN (2008, 2009)
  AND w.Price < 40
ORDER BY w.Price, w.Score DESC;
WineryNameAppellationPriceScore
Castle RockPinot NoirCentral Coast1387
Greg Norman California EstatesPinot NoirSanta Barbara County1585
TalbottKali HartSanta Lucia Highlands2187
LoringPinot NoirSanta Lucia Highlands2993
SiduriPinot NoirSanta Lucia Highlands2992
LoringPinot NoirSta. Rita Hills2988
TwomeyPinot NoirSanta Barbara County3088
SequanaSarmento VineyardSanta Lucia Highlands3288

10 rows (showing first 8)

Aggregation (GROUP BY / HAVING)

Q4. For each grape with at least 10 wines in the dataset, report the number of wines, average score and average price. Best average score first.

SELECT Grape, COUNT(*) AS NumWines,
       ROUND(AVG(Score), 1) AS AvgScore,
       ROUND(AVG(Price), 2) AS AvgPrice
FROM wine
GROUP BY Grape
HAVING COUNT(*) >= 10
ORDER BY AvgScore DESC;
GrapeNumWinesAvgScoreAvgPrice
Chardonnay10491.141.93
Cabernet Sauvingnon6891.081.29
Pinot Noir10990.746.98
Syrah6190.544.95
Grenache1090.468.80
Zinfandel7888.328.94
Sauvignon Blanc4688.224.02
Merlot1086.830.20

8 rows

Q5. For each county, report the total number of cases produced of wines that scored 90 or above. Skip appellations not tied to one county (N/A).

SELECT a.County, COUNT(*) AS NumWines, SUM(w.Cases) AS TotalCases
FROM wine w, appellations a
WHERE w.Appellation = a.Appellation
  AND w.Score >= 90
  AND a.County <> 'N/A'
GROUP BY a.County
ORDER BY TotalCases DESC;
CountyNumWinesTotalCases
Napa93293821
Sonoma121129605
Monterey1626027
Santa Barbara2425946
San Luis Obispo87049
Amador33123
San Benito32328
Mendocino31758

10 rows (showing first 8)

Q6. For each grape color, report how many wines there are, the cheapest and most expensive bottle, and how many different wineries make them.

SELECT g.Color, COUNT(*) AS NumWines,
       MIN(w.Price) AS Cheapest, MAX(w.Price) AS MostExpensive,
       COUNT(DISTINCT w.Winery) AS Wineries
FROM wine w, grapes g
WHERE w.Grape = g.Grape
GROUP BY g.Color;
ColorNumWinesCheapestMostExpensiveWineries
Red3479225199
White15310100118

2 rows

Nested Queries

Q7. Find the highest rated wine(s) from Paso Robles. Report winery, name, grape, vintage and score.

SELECT Winery, Name, Grape, Vintage, Score
FROM wine
WHERE Appellation = 'Paso Robles'
  AND Score = (SELECT MAX(Score)
               FROM wine
               WHERE Appellation = 'Paso Robles');
WineryNameGrapeVintageScore
LoringRussel Family VineyardPinot Noir200994
Linne CalodoProblem ChildZinfandel200794

2 rows

Q8. Find the wineries that made both a Zinfandel and a Syrah that scored 90 or higher.

SELECT DISTINCT Winery
FROM wine
WHERE Grape = 'Zinfandel' AND Score >= 90
  AND Winery IN (SELECT Winery
                 FROM wine
                 WHERE Grape = 'Syrah' AND Score >= 90)
ORDER BY Winery;
Winery
Carlisle
Four Vines
Martinelli
Rosenblum

4 rows

Q9. Find the "best value" wines: wines that scored above the average score for their grape but cost less than the average price for their grape. Only look at wines scoring 94+. Report grape, winery, name, score and price.

SELECT w1.Grape, w1.Winery, w1.Name, w1.Score, w1.Price
FROM wine w1
WHERE w1.Score >= 94
  AND w1.Score > (SELECT AVG(w2.Score) FROM wine w2
                  WHERE w2.Grape = w1.Grape)
  AND w1.Price < (SELECT AVG(w2.Price) FROM wine w2
                  WHERE w2.Grape = w1.Grape)
ORDER BY w1.Score DESC, w1.Price;
GrapeWineryNameScorePrice
SyrahCarlislePapa's Block9843
Cabernet SauvingnonNeyersNeyers Ranch - Conn Valley9548
SyrahRoarRosella's Vineyard9440
ChardonnayRodney StrongReserve9440
SyrahCarlisleRosella's Vineyard9443
Pinot NoirLoringRussel Family Vineyard9445
Pinot NoirLoringDurell Vineyard9445
Pinot NoirPaul HobbsPinot Noir9445

12 rows (showing first 8)

The CSU Dataset

Statistics on the 23-campus California State University system: enrollments, degrees, fees, faculty, and 2004 enrollment by discipline.

  • campuses (Id, Campus, Location, County, Year)
  • enrollments (Campus → campuses, Year, Enrolled, FTE)
  • degrees (Year, Campus → campuses, Degrees)
  • fees (Campus → campuses, Year, CampusFee)
  • faculty (Campus → campuses, Year, Faculty)
  • disciplines (Id, Name)
  • discEnr (Campus → campuses, Discipline → disciplines, Year, Undergraduate, Graduate)

Download CSU-queries.sql ↓

Selecting & Joining Tables

Q1. List all campuses that opened before 1940. Report the campus name, city and the year it opened, oldest first.

SELECT Campus, Location, Year
FROM campuses
WHERE Year < 1940
ORDER BY Year;
CampusLocationYear
San Jose State UniversitySan Jose1857
California State University-ChicoChico1887
San Diego State UniversitySan Diego1897
San Francisco State UniversitySan Francisco1899
California Polytechnic State University-San Luis ObispoSan Luis Obispo1901
Fresno State UniversityFresno1911
Humboldt State UniversityArcata1913
California Maritime AcademyVallejo1929

9 rows (showing first 8)

Q2. Report the campus fee at California Polytechnic State University-San Luis Obispo for every year from 2000 to 2005.

SELECT f.Year, f.CampusFee
FROM fees f, campuses c
WHERE f.Campus = c.Id
  AND c.Campus = 'California Polytechnic State University-San Luis Obispo'
  AND f.Year BETWEEN 2000 AND 2005
ORDER BY f.Year;
YearCampusFee
20002129
20012169
20022169
20032976
20043974
20054245

6 rows

Q3. For each year from 2000 to 2004, report the total enrollment and the number of degrees awarded at California Polytechnic State University-San Luis Obispo.

SELECT e.Year, e.Enrolled, d.Degrees
FROM campuses c, enrollments e, degrees d
WHERE c.Id = e.Campus
  AND c.Id = d.Campus
  AND e.Year = d.Year
  AND c.Campus = 'California Polytechnic State University-San Luis Obispo'
  AND e.Year BETWEEN 2000 AND 2004
ORDER BY e.Year;
YearEnrolledDegrees
2000163402840
2001175523509
2002178383169
2003175504677
2004172293374

5 rows

Q4. Report the undergraduate and graduate Engineering enrollment at every campus that offered Engineering in 2004, most undergraduates first.

SELECT c.Campus, de.Undergraduate, de.Graduate
FROM campuses c
  JOIN discEnr de ON de.Campus = c.Id
  JOIN disciplines d ON d.Id = de.Discipline
WHERE d.Name = 'Engineering' AND de.Year = 2004
ORDER BY de.Undergraduate DESC;
CampusUndergraduateGraduate
California Polytechnic State University-San Luis Obispo4943204
California State Polytechnic University-Pomona3975154
San Jose State University27841893
Long Beach State University2444361
San Diego State University1743304
California State University-Sacramento1534330
California State University-Chico129825
Fresno State University116655

17 rows (showing first 8)

Aggregation (GROUP BY / HAVING)

Q5. For each campus, report the total number of degrees awarded between 1995 and 2004 (inclusive). Most degrees first.

SELECT c.Campus, SUM(d.Degrees) AS TotalDegrees
FROM campuses c, degrees d
WHERE c.Id = d.Campus
  AND d.Year BETWEEN 1995 AND 2004
GROUP BY c.Id, c.Campus
ORDER BY TotalDegrees DESC;
CampusTotalDegrees
San Diego State University53024
California State University-Fullerton47129
Long Beach State University45568
California State University-Northridge43719
San Francisco State University42199
California State University-Sacramento40241
San Jose State University39985
California Polytechnic State University-San Luis Obispo33479

23 rows (showing first 8)

Q6. Find the counties that have more than one CSU campus. Report the county and the number of campuses.

SELECT County, COUNT(*) AS NumCampuses
FROM campuses
GROUP BY County
HAVING COUNT(*) > 1
ORDER BY NumCampuses DESC;
CountyNumCampuses
Los Angeles5
San Diego2

2 rows

Q7. Report the student-to-faculty ratio (FTE students per FTE faculty) for each campus in 2004, from highest ratio to lowest.

SELECT c.Campus, e.FTE, f.Faculty,
       ROUND(e.FTE / f.Faculty, 1) AS StudentFacultyRatio
FROM campuses c, enrollments e, faculty f
WHERE c.Id = e.Campus
  AND c.Id = f.Campus
  AND e.Year = 2004 AND f.Year = 2004
ORDER BY StudentFacultyRatio DESC;
CampusFTEFacultyStudentFacultyRatio
California State University-Monterey Bay3578151.423.6
Sonoma State University6778288.123.5
California State University-San Marcos5854257.422.7
California State University-Fullerton243951111.621.9
California State University-Chico14161656.021.6
California State University-San Bernardino12637597.021.2
California State University-Northridge234851112.121.1
California State Polytechnic University-Pomona15528736.821.1

23 rows (showing first 8)

Nested Queries

Q8. Find the campus(es) with the most undergraduate Computer and Info. Sciences students in 2004. Report campus and number of students.

SELECT c.Campus, de.Undergraduate
FROM campuses c, discEnr de, disciplines d
WHERE c.Id = de.Campus
  AND d.Id = de.Discipline
  AND d.Name = 'Computer and Info. Sciences'
  AND de.Year = 2004
  AND de.Undergraduate = (SELECT MAX(de2.Undergraduate)
                          FROM discEnr de2, disciplines d2
                          WHERE d2.Id = de2.Discipline
                            AND d2.Name = 'Computer and Info. Sciences'
                            AND de2.Year = 2004);
CampusUndergraduate
San Jose State University2025

1 row

Q9. Find the campuses whose 2005 campus fee was higher than the average campus fee across all CSU campuses that year. Highest fee first.

SELECT c.Campus, f.CampusFee
FROM campuses c, fees f
WHERE c.Id = f.Campus
  AND f.Year = 2005
  AND f.CampusFee > (SELECT AVG(CampusFee)
                     FROM fees
                     WHERE Year = 2005)
ORDER BY f.CampusFee DESC;
CampusCampusFee
California Polytechnic State University-San Luis Obispo4245
Sonoma State University3616
California Maritime Academy3446
California State University-Chico3370
California State University-Bakersfield3318
San Jose State University3292
Humboldt State University3167

7 rows