# ORDER By, GROUP By, HAVING Applying structure and performance considerations when querying data is paramount. `ORDER BY` provides sorted result sets, essential for presentation and predictable processing. `GROUP BY` aggregates data, enabling summary reporting and analytical operations, often combined with functions like `COUNT`, `MIN `, or `MAX`. The `HAVING` clause refines these aggregations, filtering grouped data based on conditions applied after aggregation. ## ORDER BY Use `ORDER BY` to enforce a specific order on your query results. Specify one or more columns ; multiple columns are comma-separated. Consider a simple selection from a `users` table without ordering: ```sql SELECT id, username FROM users; ``` Typical output without `ORDER BY` relies on internal database storage order (often clustered by primary key), not a guaranteed sequence: | id | username | | :-- | :------------ | | 2 | shinobi | | 3 | Java Team Six | | 4 | tony | | 5 | shinobi | | 6 | Java Team Six | | 7 | tony | To ensure results are sorted by username alphabetically (ascending): ```sql SELECT id, username FROM users ORDER BY username; ``` Output ordered by `username`: | id | username | | :-- | :------------ | | 2 | shinobi | | 5 | shinobi | | 3 | Java Team Six | | 6 | Java Team Six | | 4 | tony | | 7 | tony | `ORDER BY` defaults to ascending (`ASC`). Explicitly specify `DESC` for descending order. Sort usernames in reverse alphabetical order: ```sql SELECT id, username FROM users ORDER BY username DESC; ``` Output in descending username order: | id | username | | :-- | :------------ | | 4 | tony | | 7 | tony | | 3 | Java Team Six | | 6 | Java Team Six | | 2 | shinobi | | 5 | shinobi | Place `ORDER BY` after the `WHERE` clause when both are used. ## GROUP BY `GROUP BY` aggregates rows with identical values in specified columns into summary rows. This clause is typically used with aggregate functions (`COUNT`, `SUM`, `AVG`, `MIN`, `MAX`) to perform calculations on each group. To count users sharing the same username: ```sql SELECT COUNT(username), username FROM users GROUP BY username; ``` This groups users by identical usernames and counts entries within each group: | COUNT(username) | username | |:-------------- | :------------ | | 2 | shinobi | | 2 | Java Team Six | | 2 | tony | `GROUP BY` follows `FROM` and `WHERE` clauses. ## HAVING Clause `HAVING` filters groups created by `GROUP BY`. Unlike `WHERE`, which filters individual rows before grouping, `HAVING` filters grouped rows based on conditions, often involving aggregate functions. Identify usernames that appear more than once: ```sql SELECT COUNT (username), username FROM users GROUP BY username HAVING COUNT(username) > 1; ``` This groups users by username, counts occurrences, and then filters to show only groups where the count is greater than 1: | COUNT(username) | username | | :-------------- | :------------ | | 2 | shinobi | | 2 | Java Team Six | | 2 | tony | `WHERE` filters rows before aggregation; `HAVING` filters groups after aggregation.