Download presentation
Presentation is loading. Please wait.
1
Aggregates on Groups of Rows If you want to use aggregate functions to return more than one row of data you can use the GROUP BY clause. You use the GROUP BY clause with aggregate functions such as count or avg to get counts or averages for groups of rows.
2
Group By clause videoIdAverage CostTotal CostCount 101$2.49$4.982 112$1.99 1 113$2.49$7.473 77564$3.35 1 99787$3.95 1 SELECT videoId, avg(cost) as [Average Cost], sum(cost) as [Total Cost], count(*) as [Count] FROM PreviousRental GROUP BY videoId;
3
accountIdvideoIddateRenteddateDuecost 1031011/3/20021/4/2002$1.59 1011114/24/20025/2/2002$3.99 1011124/24/20024/30/2002$1.99 1011132/22/20022/25/2002$3.00 1011142/22/20022/25/2002$3.00 10312312/1/200112/31/2001$10.99 1011452/14/20022/16/2002$1.99 101775644/24/2002 101909871/1/20021/8/2002$2.99 101997871/1/20021/4/2002$3.49 Rental accountIdvideoIddateRenteddateReturnedcost 101 12/9/200112/10/2001$2.49 1011121/13/20011/4/2001$1.99 1011131/15/2002 $0.99 10211312/1/200112/3/2001$2.49 11110112/4/200112/6/2001$2.49 111997871/1/20021/4/2002$3.95 20111312/9/200112/14/2001$3.99 201775641/14/20021/24/2002$3.35 PreviousRental
4
Group By multiple columns We can also group by multiple columns. But columns in your select statement are restricted to those that are in your group by clause. You must group by at least those non-aggregate expressions in your SELECT. In other words, each row in the result must have unique values for all non calculated attributes.
5
SELECT c.accountId, lastName, firstName, count(*) as [Number Rented] FROM Customer c INNER JOIN Rental r ON c.accountId=r.accountId GROUP BY c.accountId, lastName, firstName; accountIdlastNamefirstNameNumber Rented 101BlockJane8 103HarrisonKatherine2
6
Bad Group By What’s wrong with this SELECT statement? SELECT c.accountId, lastName, firstName, count(*) as [Number Rented] FROM Customer c INNER JOIN Rental r ON c.accountId=r.accountId GROUP BY lastName, firstName; “You tried to execute a query that does not include the specified expression ‘accountId’ as part of an aggregate function. You can use accountId in an aggregate function, but not as an output column because it is not guaranteed to be unique in the groups (by firstName)
7
Good or Bad? SELECT lastName, firstName FROM Customer GROUP BY lastName, firstName, city, state; lastNamefirstName BlockJane BreauxCarroll DoeJane DoeJane GreavesJoseph HamiltonCherry HarrisonKatherine MorehouseAnita MylopoulosJanet O'ConnellJanet RiccardiGreg
8
accountIdlastNamefirstNamestreetcitystatezipcodebalance 101BlockJane345 Randolph CircleApopkaFL30458-$0.00 102HamiltonCherry3230 Dade St.Dade CityFL30555-$3.47 103HarrisonKatherine103 Landis HallBrattFL30457-$30.57 104BreauxCarroll76 Main St.ApopkaFL30458-$34.58 106MorehouseAnita9501 Lafayette St.HoumaLA44099-$0.00 111DoeJane123 Main St.ApopkaFL30458-$0.00 201GreavesJoseph14325 N. Bankside St.GodfreyIL43580-$0.00 444DoeJaneCawthon Dorm, room 642TallahasseeFL32306-$0.00 445RiccardiGreg101 Thanet St.LondonFL33333-$0.00 446RiccardiGreg101 Thanet St.LondonFL33333-$0.00 447RiccardiGreg101 Thanet St.LondonFL33333-$0.00 448MylopoulosJanet4402 Elm St.ApopkaFL33455-$0.00 449MylopoulosJanet4402 Elm St.ApopkaFL33455-$0.00 450MylopoulosJanet4402 Elm St.ApopkaFL33455-$0.00 451O'ConnellJanet4402 Elm St.ApopkaFL33455-$0.00 452O'ConnellJanet4402 Elm St.ApopkaFL33455-$0.00 Customer ssnlastNamefirstName 145-09-0967UnoJane 245-11-4554ToulouseJie 376-77-0099ThreatAyisha 479-98-0098FortuneJulian 579-98-8778FivozinskyBruce Employee
9
Having clause You can also restrict which groups produce output rows. This is done by using a Having clause which works just like a WHERE clause of a regular SELECT statement accountIdlastNamefirstNameNumber Rented 101BlockJane8 SELECT c.accountId, lastName, firstName, count(*) as [Number Rented] FROM Customer c INNER JOIN Rental r ON c.accountId=r.accountId GROUP BY c.accountId, firstName, lastName HAVING count(*) > 5;
10
SELECT m.title, m.genre, COUNT(*) AS numRentals, AVG(u.cost) AS average, SUM(u.cost) AS [sum] FROM ((SELECT * FROM Rental UNION SELECT * FROM PreviousRental) as u INNER JOIN (Movie m INNER JOIN Video v ON m.movieId=v.movieId) ON u.videoId=v.videoId) WHERE m.genre like '*comedy*' GROUP BY m.title, m.genre, m.movieId HAVING COUNT(*)>1; titlegenrenumRentalsaveragesum Animal Housecomedy3$3.18$6.35 Annie Hallromantic comedy8$3.68$29.43 Duck Soupcomedy2$3.72$7.44
11
WHERE OR HAVING Should conditionals be in the WHERE or HAVING clause? This query yields the same results as the previous. SELECT m.title, m.genre, COUNT(*) AS numRentals, AVG(u.cost) AS average, SUM(u.cost) AS [sum] FROM ((SELECT * FROM Rental UNION SELECT * FROM PreviousRental) as u INNER JOIN (Movie m INNER JOIN Video v ON m.movieId=v.movieId) ON u.videoId=v.videoId) GROUP BY m.title, m.genre, m.movieId HAVING COUNT(*)>1 AND m.genre like '*comedy*';
12
NULLS in Aggregates What happens with NULLS in aggregates? For purposes of calculation, such as with SUM, COUNT, etc, NULLS are not counted. For purposes of grouping, NULLS will be grouped together.
13
SELECT COUNT(videoId) AS [videoIds], COUNT(dateDue) as [dueDates], dateDue FROM Rental GROUP BY dateDue; videoIdsdueDatesdateDue 10 1112/31/2001 221/4/2002 111/8/2002 112/16/2002 222/25/2002 114/30/2002 115/2/2002
14
A Challenge Find customers (accountID, firstName, LastName) who have rented (currently or previously) every movie BigHit has in the db. Include the number of distinct movies rented. [Unfortunately, there aren’t any customers that have rented every movie. Jane Block has rented every movie in the db for which BigHit has videos] How might you approach this? Get count of movies rented by customer Then compare that count to the num of movies that BigHit has. If equal then they’ve rented all.
15
movieIdtitlegenrelengthrating 101The Thirty-Nine Stepsmystery101R 123Annie Hallromantic comedy110R 145Lady and the Trampanimated comedy93PG 189Animal Housecomedy87PG-13 450Elizabethcostume drama123PG-13 553Stagecoachwestern130R 987Duck Soupcomedy99PG-13 Movie
16
SELECT u.accountId, lastName, firstName, v.movieId FROM ((SELECT p.accountId, p.videoId FROM previousRental p UNION SELECT r.accountId, r.videoId FROM rental r) u INNER JOIN Customer c ON u.accountId=c.accountId) INNER JOIN video v ON u.videoId=v.videoId GROUP BY u.accountId, lastName, firstName, v.movieId First let’s get all distinct movieIds for each rental and previousrental, join with customer to get cust info. Could I have used DISTINCT instead of GROUP BY?
17
accountIdlastNamefirstNamemovieId 101BlockJane101 BlockJane123 101BlockJane145 101BlockJane189 101BlockJane450 101BlockJane987 102HamiltonCherry123 103HarrisonKatherine101 103HarrisonKatherine123 111DoeJane101 111DoeJane987 201GreavesJoseph123 201GreavesJoseph189
18
SELECT cm.accountId, cm.lastName, cm.firstName, COUNT(cm.movieId) AS [Movies Rented] FROM [SELECT u.accountId, lastName, firstName, v.movieId FROM (((SELECT p.accountId, p.videoId FROM previousRental p UNION SELECT r.accountId, r.videoId FROM rental r) u INNER JOIN Customer c ON u.accountId=c.accountId) INNER JOIN video v ON u.videoId=v.videoId) GROUP BY u.accountId, lastName, firstName, v.movieId]. AS cm GROUP BY cm.accountId, cm.lastName, cm.firstName Now let’s group those results to get count of movieIds for each customer. That is, for each customer we’ll calculate the number of movies they’ve previously rented or are currently renting.
19
accountIdlastNamefirstNameMovies Rented 101BlockJane6 102HamiltonCherry1 103HarrisonKatherine2 111DoeJane2 201GreavesJoseph2
20
SELECT cm.accountId, cm.lastName, cm.firstName, COUNT(cm.movieId) AS [Movies Rented] FROM [SELECT u.accountId, lastName, firstName, v.movieId FROM (((SELECT p.accountId, p.videoId FROM previousRental p UNION SELECT r.accountId, r.videoId FROM rental r) u INNER JOIN Customer c ON u.accountId=c.accountId) INNER JOIN video v ON u.videoId=v.videoId) GROUP BY u.accountId, lastName, firstName, v.movieId]. AS cm GROUP BY cm.accountId, cm.lastName, cm.firstName HAVING COUNT(cm.movieId)=(SELECT COUNT(*) FROM movie); There are no customers that have rented all 7 movies because there is no video of movie 553 Finally, let’s compare that count with the number of movies in the movie table. If equal then the customer has rented all of them, otherwise they haven’t.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.