Aggregates are more popular here than any other topic, in the last two years by about 4 to 1 over the next most popular category. Basic aggregation is the simplest grouping query pattern: for column foo, display the count, the smallest, the largest, the sum, the average or some other statistic of column bar values. For example, the minimum bar value per foo:
Return the highest bar value for each foo, ordering top to bottom by that value:
Ditto for AVG(), COUNT() etc. The pattern easily extends to multiple grouping column expressions.Suppose you want to see which of four bands of counts each foo count falls into? Since MySQL 8 and MariaDB 10 implemented Window functions, you can just add an NTILE call to a standard aggregating query invoking COUNT(*) :
Here NTILE() specifies how many rowsets (or partitions, or windows) to break the result into, and OVER() specifies which result column(s) should be thus partitioned. For more about Window functions see "Windowing: Introduction". For aggregating functions like MIN() and MAX() that return a single value, there may be multiple instances of the result. If you wish to see them, put the aggregating query in a subquery and join to it from a direct query on the table:
MySQL introduced the SQL extension GROUP_CONCAT() , which makes short work of listing items in groups. For example, given a table of suppliers and the parts they make ...
List suppliers for each part:
When there are several tables to be joined, the beginner may feel overwhelmed by the complexity of the problem. Suppose you're asked to retrieve the top computer desk salesperson for this schema:
Two rules of thumb help with problems like this: solve one step at a time, and work from inside out. Here "inside out" means start by building the join list needed to retrieve sales data:
Test those joins with a query that just lists sales data:
Now we just need to filter for 'computer desk' sales, add aggregation, and pick off the top seller:
If columns other than the GROUP BY columns must be retrieved, and if the grouping expression does not have a strictly 1:1 relationship with (ie., are not "functionally dependent" on) those columns, then to avoid returning arbitrary values for those non-grouping columns, you need to either add those columns to the Group By clause, or put the GROUP BY query in a subquery and join that result to the other columns, for example:
If sql_mode includes ONLY_FULL_GROUP_BY , MySQL returns an error for a query that Selects non-aggregated columns that aren't functionally dependent on the grouping columns. Before version 5.7.5 MySQL, with ONLY_FULL_GROUP_BY set, blindly rejected queries like this with the message that those columns are missing from the GROUP BY expression. Starting in 5.7.5 though, MySQL is better at detecting functional dependencies, and it won't generate such an error if it concludes that the ungrouped columns are functionally dependent on grouoed columns. If it decides they aren't functionally dependent, the message says that. For full discussion of this, see Roland Bouman's excellent discussion at http://rpbouman.blogspot.nl/2014/09/mysql-575-group-by-respects-functional.html |