--- note type: - sql - database - theory date: 2026-06-03 done: link: https://app.pluralsight.com/ilx/video-courses/sql-joins-constraints-normalization-subqueries/course-overview --- # Common Aggregate Functions |title|cost|duration| |---|---|---| |Gone with the wind|390000|220| |Frankenstein|3000000|50| |Creature from the black lagoon|500000|79| |NULL|100|10| ## 1. COUNT() ## Count all rows `SELECT COUNT(*) FROM Movies;` **Output:** ``` 4 ``` - Counts all rows, including rows where columns are `NULL`. ### Count non-NULL values in a column `SELECT COUNT(title) FROM Movies;` **Output:** ``` 3 ``` - `NULL` title is **not counted**. ## 2. MIN() `SELECT MIN(cost) FROM Movies;` **Output:** ``` 100 ``` - Returns the smallest value in the column. ## 3. MAX() `SELECT MAX(cost) FROM Movies;` **Output:** ``` 3000000 ``` - Returns the largest value. ## 4. SUM() `SELECT SUM(cost) FROM Movies;` **Output:** ``` 3890100 ``` Calculation: ``` 390000 + 3000000 + 500000 + 100 = 3890100 ``` - Adds all values in the column. - Ignores `NULL` values (none in `cost` here). ## 5. AVG() `SELECT AVG(cost) FROM Movies;` **Output:** ``` 972525 ``` Calculation: ``` 3890100 / 4 = 972525 ``` - Computes the average of all values. --- ## Using Multiple Aggregates ``` SELECT     COUNT(*) AS total_movies,     MIN(cost) AS cheapest,     MAX(cost) AS most_expensive,     SUM(cost) AS total_cost,     AVG(cost) AS average_cost FROM Movies; ``` **Output:** ``` total_movies | cheapest | most_expensive | total_cost | average_cost 4 | 100 | 3000000 | 3890100 | 972525 ``` # Filtering Aggregates | title | cost | duration | genre | | ------------------------------ | ------- | -------- | ------ | | Gone with the wind | 390000 | 220 | Drama | | Frankenstein | 3000000 | 50 | Horror | | Creature from the black lagoon | 500000 | 79 | Horror | | Casablanca | 1000000 | 102 | Drama | | Toy Story | 2000000 | 81 | Family | | NULL | 100 | 10 | Horror | ## GROUP BY `GROUP BY` groups rows so aggregates are calculated per group rather than across the whole table. ``` SELECT genre, SUM(cost) AS total_cost FROM Movies GROUP BY genre; ``` Output: ``` genre | total_cost Drama | 1390000 Horror | 3500100 Family | 2000000 ``` ``` SELECT genre, AVG(duration) AS avg_duration FROM Movies GROUP BY genre; ``` Output: ``` genre | avg_duration Drama | 161 Horror | 46.33 Family | 81 ``` --- ## WHERE (filtering rows before aggregation) `WHERE` filters rows **before** grouping and aggregation. ``` SELECT genre, COUNT(*) AS num_movies FROM Movies WHERE duration > 60 GROUP BY genre; ``` Output: ``` genre | num_movies Drama | 2 Horror | 1 Family | 1 ``` Explanation: - The row with duration = 10 is excluded before grouping. ## HAVING (filtering groups after aggregation) `HAVING` filters results **after aggregation**. ``` SELECT genre, SUM(cost) AS total_cost FROM Movies GROUP BY genre HAVING SUM(cost) >= 2000000; ``` Output: ``` genre | total_cost Horror | 3500100 Family | 2000000 -- note: included only if >= was used ``` If strictly `> 2000000`, only: ``` Horror | 3500100 ``` ``` SELECT genre, COUNT(*) AS num_movies FROM Movies GROUP BY genre HAVING COUNT(*) > 2; ``` Output: ``` genre | num_movies Horror | 3 ``` ## Combined Example ``` SELECT genre, AVG(cost) AS avg_cost FROM Movies WHERE duration > 60 GROUP BY genre HAVING AVG(cost) > 1000000; ``` Steps: 1. WHERE filters rows (duration > 60) 2. GROUP BY groups remaining data 3. HAVING filters grouped results Output: ``` genre | avg_cost Family | 2000000 ```