SQL aggregate functions and grouping

SQL aggregate functions help you summarize the data in a table. For example, you can count products, find their average price or add up the prices of products in a set.

COUNT counts rows, SUM adds values, AVG calculates the average, and MIN and MAX find the minimum and maximum.

Our examples use the candy table. The price field contains the price, and filling indicates whether the candy has a filling.

id name filling price
1 Plutonian Praline true 30
2 Explosive Comet true 60
3 Universal Harmony false 20
4 Pluto's Tears false 40
5 Mint Vortex false 40
7 Plutonic Cream false 70
10 Pluto Mystery true 90

The candy table

COUNT — counting rows

With the “With filling” filter on, the catalogue shows three items. Check both the number of items and how many have a price.

COUNT(*) Counts all rows that match the filter.
COUNT(price) Counts rows that have a price.

AS gives a result column a name. Here, candies is the number of candies and prices is the number of recorded prices.

SELECT COUNT(*) AS candies,
       COUNT(price) AS prices
FROM candy
WHERE filling = true;
candies prices
3 3

All three filled candies have a price. Removing WHERE makes the count include all seven items in the catalogue.

SUM, AVG, MIN and MAX — checking prices

Calculate the total, average, lowest and highest prices of candies with a filling.

SUM Adds the prices of the selected candies.
AVG Calculates the arithmetic mean of the prices.
MIN Finds the lowest price.
MAX Finds the highest price.
SELECT SUM(price) AS total,
       AVG(price) AS mean_price,
       MIN(price) AS lowest,
       MAX(price) AS highest
FROM candy
WHERE filling = true;
total mean_price lowest highest
180 60 30 90

The three prices are 30, 60 and 90. That gives a total of 180 and an average of 180 / 3 = 60 per candy. The lowest and highest prices are 30 and 90.

Grouping with GROUP BY

The report shows two totals, one for filled candies and one for candies without a filling. Group the rows by filling to check both in one query.

GROUP BY collects rows with the same field value. SUM calculates a separate total for each group. The filling column in the result identifies the group.

In this example, filling appears twice. In GROUP BY it groups the candies by whether they have a filling. In SELECT it shows which group each total belongs to.

SELECT filling, SUM(price) AS total
FROM candy
GROUP BY filling;
filling total
true 180
false 170

The three filled varieties total 180 and the four without a filling total 170. The two report rows should add up to the total for the whole catalogue.

Filtering groups with HAVING

Look for candies that share both a price and a filling status. Return only the combinations that occur more than once.

List both fields in GROUP BY, separated by a comma. Each group now represents one combination of filling and price. COUNT(*) gives the number of rows in that group.

HAVING filters groups by a condition. In this example, keep only groups containing two or more candies.

SELECT filling, price, COUNT(*) AS qty
FROM candy
GROUP BY filling, price
HAVING COUNT(*) > 1;
filling price qty
false 40 2

Pluto's Tears and Mint Vortex both cost 40 and neither has a filling. Every other combination has only one row.

WHERE filters individual rows before grouping. HAVING filters groups after their totals have been calculated.

WHERE COUNT(*) > 1 causes an error because the size of a group is still unknown when rows are filtered. Use WHERE price > 40 to check the price of each candy or HAVING AVG(price) > 40 to check the average for each group.

Task

The shop puts together candy sets. Check how their prices are calculated using the candy table.

Rules for assembling the sets:

  • Candies with and without a filling go into separate sets.
  • Only candies priced from 30 to 70, inclusive, are included in a set.
  • A set can go on sale if it contains at least three candies.

Write an SQL query that calculates the price of the set eligible for sale.

tester_today Learning database
⌘ / Ctrl + Enter
Query results
Ready to run
Task available to premium users!

Unlock access to learn without limits.

Full access to all practical tasks
Answer checking
Unlimited attempts