Review Aggregate Functions
- Aaggregate function computes value for entire column - SELECT AVG(number) FROM TableName;
- Unless it is paired with a filter - SELECT AVG(number) FROM TableName WHERE text = 'Something';
- If you want to get the average of a different group of rows, need another query - SELECT AVG(number) FROM TableName WHERE text = 'Something else';
Group By
- To perform aggregate functions on groups of rows without multiple queries, use GROUP BY - SELECT text, AVG(number) FROM TableName GROUP BY text;
- Can group by more than one column - SELECT text, date, AVG(number) FROM TableName GROUP BY text, date;
- All columns with the same two columns are grouped
- Just like with non-group aggregate functions, non-aggregate columns can not be included - SELECT id, text, AVG(number) FROM TableName GROUP BY text; -- Error
- Can not use derived columns in group by - SELECT CONCAT(text1, text2) AS text, AVG(number) FROM TableName GROUP BY text; -- Error SELECT CONCAT(text1, text2), AVG(number) FROM TableName GROUP BY CONCAT(text1, text2); -- Error in some implementation of SQL
- If you do want to group by a derived column, need to use a subquery - SELECT text, AVG(number) FROM (SELECT CONCAT(text1, text2) AS text, number FROM TableName) AS Concatenated GROUP BY text;
- Or if possible just use the two separtate columns in the group by - SELECT text1, text2, AVG(number) FROM TableName GROUP BY text1, text2;
- Groups can be used with joins - SELECT text, AVG(number) FROM Table1 INNER JOIN Table2 GROUP BY text;
- With filters - SELECT text, AVG(number) FROM Table1 WHERE number > 0 GROUP BY text;
- With ordering - SELECT text, AVG(number) FROM Table1 GROUP BY text ORDER BY text DESC; SELECT text, AVG(number) FROM Table1 GROUP BY text ORDER BY AVG(number);
- Inside of the filter clause
- First an example of an agrregate function in the WHERE clause - SELECT * FROM TableName WHERE number > (SELECT AVG(number) FROM TableName);
- Now add GROUP BY - SELECT * FROM TableName WHERE number > (SELECT AVG(number) FROM TableName GROUP BY text); -- Error
- But this is comparing a single number to a table of numbers
- Which produces an error
- To prevent, use greater than all operator - SELECT * FROM TableName WHERE number > ALL (SELECT AVG(number) FROM TableName GROUP BY text);
- There is also a greater than any comparison - SELECT * FROM TableName WHERE number > ANY (SELECT AVG(number) FROM TableName GROUP BY text);
- Can also filter the grouped aggregate rows - SELECT text, AVG(number) FROM TableName GROUP BY text WHERE AVG(number) > 3; -- Error
- This doesn’t work because the WHERE clause of a select statement goes before the GROUP BY and is performed before the grouping
- To filter the grouped rows use HAVING keyword - SELECT text, AVG(number) FROM TableName GROUP BY text HAVING AVG(number) > 3;