❖ Grouping  | 
SELECT-FROM-WHEREGROUP BY
❖ Grouping (cont)  | 
Example: How many different beers does each brewer make?
SELECT   brewer, COUNT(name) as nbeers
FROM     Beers
GROUP BY brewer;
       brewer        | nbeers 
---------------------+--------
 West City           |      1
 James Squire        |      5
 Yullis              |      1
 Hop Nation          |      4
 Anderson Valley     |      1
 Beatnik             |      1
 Boatrocker          |      3
 Kizakura            |      1
 ...
❖ Grouping (cont)  | 
GROUP BY
SELECT attributes/aggregations FROM relations WHERE condition GROUP BY attributes
Semantics:
SELECT-FROM-WHERE❖  Restrictions on  SELECT | 
When using grouping, every attribute in the SELECT
GROUP-BYSELECT brewer, style FROM Beers GROUP BY brewer;
PostgreSQL's response to this query:
ERROR: column beers.style must appear in the GROUP BY 
         clause or be used in an aggregate function
❖ Filtering Groups  | 
In some queries, you can use the WHERE
Example: Average beer price by suburb excluding hotels in The Rocks.
SELECT b.addr, AVG(s.price) FROM Sells s join Bars b on (s.bar=b.name) WHERE b.addr <> 'The Rocks' GROUP BY b.addr;
For conditions on whole groups, use the HAVING
❖ Filtering Groups (cont)  | 
HAVINGGROUP-BY
SELECT attributes/aggregations FROM relations WHERE condition1 (on tuples) GROUP BY attributes HAVING condition2; (on group)
Semantics of HAVING
GROUP-BYHAVING❖ Filtering Groups (cont)  | 
Example: Number of styles from brewers who make at least 5 beers?
SELECT   brewer, count(name) as nbeers,
         count(distinct style) as nstyles
FROM     Beers
GROUP BY brewer
HAVING   count(name) > 4
ORDER BY brewer;
      brewer       | nbeers | nstyles 
-------------------+--------+---------
 Bentspoke         |      9 |       7
 Carlton           |      5 |       2
 Frenchies         |      5 |       5
 Hawkers           |      5 |       5
 James Squire      |      5 |       4
 One Drop          |      9 |       7
 Sierra Nevada     |      5 |       5
 Tallboy and Moose |      5 |       5
distinctnbeers=nstyles
❖ Filtering Groups (cont)  | 
Alternative formulation of division using  GROUP-BYHAVING
Example: Find bars that each sell all of the beers Justin likes.
SELECT DISTINCT S.bar
FROM   Sells S, Likes L on (S.beer = L.beer)
WHERE  L.drinker = 'Justin'
GROUP  BY S.bar
HAVING count(S.beer) =
           (SELECT count(beer) FROM Likes
            WHERE drinker = 'Justin');
❖ Partitions  | 
Sometimes it is useful to
GROUP-BYGROUP-BYPARTITION❖ Partitions (cont)  | 
Syntax for PARTITION
SELECT attr1, attr2, ...,
       aggregate1 OVER (PARTITION BY attri),
       aggregate2 OVER (PARTITION BY attrj), ...
FROM   Table
WHERE  condition on attributes
Note: the condition cannot include the aggregate value(s)
❖ Partitions (cont)  | 
Example: show each city with daily temperature and temperature range
Schema: Weather(city,date,temperature)
SELECT city, date, temperature
       min(temperature) OVER (PARTITION BY city) as lowest,
       max(temperature) OVER (PARTITION BY city) as highest
FROM   Weather;
Output: Result(city, date, temperature, lowest, highest)
❖ Partitions (cont)  | 
Example showing  GROUP BYPARTITION
SELECT city, min(temperature) max(temperature) FROM Weather GROUP BY city
Result: one tuple for each city Result(city,min,max)
SELECT city,  date,  temperature as temp,
       min(temperature) OVER (PARTITION BY city),
       max(temperature) OVER (PARTITION BY city)
FROM   Weather;
Result: one tuple for each temperature measurement.
Produced: 5 Oct 2020