SQL queries from my Database Management Systems course, written against three relational datasets: a bakery's sales, California wine ratings, and the CSU campus system.
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.
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.
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;
| Flavor | Food | Price |
|---|---|---|
| Chocolate | Meringue | 1.25 |
| Chocolate | Croissant | 1.75 |
| Chocolate | Eclair | 3.25 |
| Chocolate | Tart | 3.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;
| RNumber | SaleDate |
|---|---|
| 66227 | 2007-10-10 |
| 81517 | 2007-10-10 |
| 44590 | 2007-10-12 |
| 85881 | 2007-10-13 |
| 72207 | 2007-10-15 |
| 86085 | 2007-10-16 |
| 37636 | 2007-10-20 |
| 45062 | 2007-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;
| LastName | FirstName |
|---|---|
| ARZT | TERRELL |
| CALLENDAR | DAVID |
| DUNLOW | OSVALDO |
| HAFFERKAMP | CUC |
| HELING | RUPERT |
| STADICK | MIGDALIA |
| TOUSSAND | SHARRON |
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;
| Flavor | Food | Price | FirstName | LastName |
|---|---|---|---|---|
| Truffle | Cake | 15.95 | TRAVIS | ESPOSITA |
| Lemon | Cake | 8.95 | TRAVIS | ESPOSITA |
| Apple | Pie | 5.25 | CUC | HAFFERKAMP |
3 rows
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;
| LastName | FirstName | Purchases | TotalSpent |
|---|---|---|---|
| HELING | RUPERT | 18 | 206.61 |
| SLINGLAND | JOSETTE | 15 | 190.41 |
| TOUSSAND | SHARRON | 16 | 187.70 |
| LOGAN | JULIET | 11 | 163.19 |
| SOPKO | RAYFORD | 15 | 147.60 |
| CRUZEN | ARIANE | 11 | 145.22 |
| ZEME | STEPHEN | 16 | 137.16 |
| DUKELOW | CORETTA | 8 | 119.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;
| Food | NumProducts | Cheapest | MostExpensive | AvgPrice |
|---|---|---|---|---|
| Cake | 7 | 8.95 | 15.95 | 13.03 |
| Tart | 10 | 3.25 | 3.75 | 3.40 |
| Croissant | 5 | 1.45 | 1.75 | 1.57 |
| Cookie | 7 | 0.79 | 1.25 | 1.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;
| SaleDate | Receipts | Revenue |
|---|---|---|
| 2007-10-12 | 11 | 169.87 |
| 2007-10-04 | 8 | 137.79 |
| 2007-10-10 | 10 | 131.92 |
| 2007-10-16 | 9 | 112.97 |
| 2007-10-09 | 10 | 112.97 |
| 2007-10-19 | 5 | 111.78 |
| 2007-10-07 | 10 | 104.98 |
7 rows
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);
| Flavor | Food | TimesBought |
|---|---|---|
| Apple | Tart | 25 |
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;
| LastName | FirstName |
|---|
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;
| Flavor | Food | Price | AvgForFood |
|---|---|---|---|
| Casino | Cake | 15.95 | 13.03 |
| Opera | Cake | 15.95 | 13.03 |
| Truffle | Cake | 15.95 | 13.03 |
| Napoleon | Cake | 13.49 | 13.03 |
| Marzipan | Cookie | 1.25 | 1.07 |
| Tuile | Cookie | 1.25 | 1.07 |
| Ganache | Cookie | 1.15 | 1.07 |
| Gongolais | Cookie | 1.15 | 1.07 |
16 rows (showing first 8)
500 single-grape California wines rated by Wine Spectator magazine (2007–2011), with information about each grape and each grape-growing region (appellation).
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;
| Winery | Name | Vintage | Score | Price |
|---|---|---|---|---|
| Hourglass | Cabernet Sauvignon | 2006 | 97 | 135 |
| Chappellet | Pritchard Hill | 2007 | 96 | 135 |
| Darioush | Darius II | 2007 | 96 | 225 |
| Neyers | Neyers Ranch - Conn Valley | 2007 | 95 | 48 |
| Ramey | Annum | 2007 | 95 | 85 |
| Dancing Hares | Cabernet Sauvignon | 2005 | 95 | 95 |
| Lewis | Reserve | 2006 | 95 | 125 |
| Lewis | Reserve | 2007 | 95 | 130 |
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;
| Grape | Winery | Appellation | Name | Score |
|---|---|---|---|---|
| Chardonnay | DuMOL | Sonoma County | Green River Isobel | 95 |
| Chardonnay | Kistler | Sonoma County | McCrea Vineyard | 95 |
| Chardonnay | Maybach | Sonoma Coast | Eterium B. Thieriot Vineyard | 95 |
| Chardonnay | Peter Michael | Sonoma County | Ma Belle-Fille | 95 |
| Chardonnay | Three Sticks | Sonoma Valley | Durell Vineyard | 95 |
| Chardonnay | Tor | Sonoma Valley | Durell Vineyard Wente Clone | 95 |
| Chardonnay | Failla | Sonoma Coast | Estate Vineyard | 94 |
| Chardonnay | Kistler | Russian River Valley | Wine Hill Vineyard | 94 |
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;
| Winery | Name | Appellation | Price | Score |
|---|---|---|---|---|
| Castle Rock | Pinot Noir | Central Coast | 13 | 87 |
| Greg Norman California Estates | Pinot Noir | Santa Barbara County | 15 | 85 |
| Talbott | Kali Hart | Santa Lucia Highlands | 21 | 87 |
| Loring | Pinot Noir | Santa Lucia Highlands | 29 | 93 |
| Siduri | Pinot Noir | Santa Lucia Highlands | 29 | 92 |
| Loring | Pinot Noir | Sta. Rita Hills | 29 | 88 |
| Twomey | Pinot Noir | Santa Barbara County | 30 | 88 |
| Sequana | Sarmento Vineyard | Santa Lucia Highlands | 32 | 88 |
10 rows (showing first 8)
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;
| Grape | NumWines | AvgScore | AvgPrice |
|---|---|---|---|
| Chardonnay | 104 | 91.1 | 41.93 |
| Cabernet Sauvingnon | 68 | 91.0 | 81.29 |
| Pinot Noir | 109 | 90.7 | 46.98 |
| Syrah | 61 | 90.5 | 44.95 |
| Grenache | 10 | 90.4 | 68.80 |
| Zinfandel | 78 | 88.3 | 28.94 |
| Sauvignon Blanc | 46 | 88.2 | 24.02 |
| Merlot | 10 | 86.8 | 30.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;
| County | NumWines | TotalCases |
|---|---|---|
| Napa | 93 | 293821 |
| Sonoma | 121 | 129605 |
| Monterey | 16 | 26027 |
| Santa Barbara | 24 | 25946 |
| San Luis Obispo | 8 | 7049 |
| Amador | 3 | 3123 |
| San Benito | 3 | 2328 |
| Mendocino | 3 | 1758 |
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;
| Color | NumWines | Cheapest | MostExpensive | Wineries |
|---|---|---|---|---|
| Red | 347 | 9 | 225 | 199 |
| White | 153 | 10 | 100 | 118 |
2 rows
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');
| Winery | Name | Grape | Vintage | Score |
|---|---|---|---|---|
| Loring | Russel Family Vineyard | Pinot Noir | 2009 | 94 |
| Linne Calodo | Problem Child | Zinfandel | 2007 | 94 |
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;
| Grape | Winery | Name | Score | Price |
|---|---|---|---|---|
| Syrah | Carlisle | Papa's Block | 98 | 43 |
| Cabernet Sauvingnon | Neyers | Neyers Ranch - Conn Valley | 95 | 48 |
| Syrah | Roar | Rosella's Vineyard | 94 | 40 |
| Chardonnay | Rodney Strong | Reserve | 94 | 40 |
| Syrah | Carlisle | Rosella's Vineyard | 94 | 43 |
| Pinot Noir | Loring | Russel Family Vineyard | 94 | 45 |
| Pinot Noir | Loring | Durell Vineyard | 94 | 45 |
| Pinot Noir | Paul Hobbs | Pinot Noir | 94 | 45 |
12 rows (showing first 8)
Statistics on the 23-campus California State University system: enrollments, degrees, fees, faculty, and 2004 enrollment by discipline.
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;
| Campus | Location | Year |
|---|---|---|
| San Jose State University | San Jose | 1857 |
| California State University-Chico | Chico | 1887 |
| San Diego State University | San Diego | 1897 |
| San Francisco State University | San Francisco | 1899 |
| California Polytechnic State University-San Luis Obispo | San Luis Obispo | 1901 |
| Fresno State University | Fresno | 1911 |
| Humboldt State University | Arcata | 1913 |
| California Maritime Academy | Vallejo | 1929 |
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;
| Year | CampusFee |
|---|---|
| 2000 | 2129 |
| 2001 | 2169 |
| 2002 | 2169 |
| 2003 | 2976 |
| 2004 | 3974 |
| 2005 | 4245 |
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;
| Year | Enrolled | Degrees |
|---|---|---|
| 2000 | 16340 | 2840 |
| 2001 | 17552 | 3509 |
| 2002 | 17838 | 3169 |
| 2003 | 17550 | 4677 |
| 2004 | 17229 | 3374 |
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;
| Campus | Undergraduate | Graduate |
|---|---|---|
| California Polytechnic State University-San Luis Obispo | 4943 | 204 |
| California State Polytechnic University-Pomona | 3975 | 154 |
| San Jose State University | 2784 | 1893 |
| Long Beach State University | 2444 | 361 |
| San Diego State University | 1743 | 304 |
| California State University-Sacramento | 1534 | 330 |
| California State University-Chico | 1298 | 25 |
| Fresno State University | 1166 | 55 |
17 rows (showing first 8)
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;
| Campus | TotalDegrees |
|---|---|
| San Diego State University | 53024 |
| California State University-Fullerton | 47129 |
| Long Beach State University | 45568 |
| California State University-Northridge | 43719 |
| San Francisco State University | 42199 |
| California State University-Sacramento | 40241 |
| San Jose State University | 39985 |
| California Polytechnic State University-San Luis Obispo | 33479 |
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;
| County | NumCampuses |
|---|---|
| Los Angeles | 5 |
| San Diego | 2 |
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;
| Campus | FTE | Faculty | StudentFacultyRatio |
|---|---|---|---|
| California State University-Monterey Bay | 3578 | 151.4 | 23.6 |
| Sonoma State University | 6778 | 288.1 | 23.5 |
| California State University-San Marcos | 5854 | 257.4 | 22.7 |
| California State University-Fullerton | 24395 | 1111.6 | 21.9 |
| California State University-Chico | 14161 | 656.0 | 21.6 |
| California State University-San Bernardino | 12637 | 597.0 | 21.2 |
| California State University-Northridge | 23485 | 1112.1 | 21.1 |
| California State Polytechnic University-Pomona | 15528 | 736.8 | 21.1 |
23 rows (showing first 8)
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);
| Campus | Undergraduate |
|---|---|
| San Jose State University | 2025 |
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;
| Campus | CampusFee |
|---|---|
| California Polytechnic State University-San Luis Obispo | 4245 |
| Sonoma State University | 3616 |
| California Maritime Academy | 3446 |
| California State University-Chico | 3370 |
| California State University-Bakersfield | 3318 |
| San Jose State University | 3292 |
| Humboldt State University | 3167 |
7 rows