Skip to content

Commit

Permalink
Refactor SQL queries (#29113)
Browse files Browse the repository at this point in the history
- Updated `GROUP BY` clause to include `users.name` for adherence to
  best practices.
- Modified `HAVING` clause to reference `COUNT(posts.id)` directly
  instead of the alias `posts_written` aligning with the SQL execution
  order, as column aliases are not available during the HAVING phase.
  • Loading branch information
dekr1sh authored Nov 25, 2024
1 parent 1afa0f5 commit 51b84f8
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions databases/databases/databases_and_sql.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ Now we're getting into the fun stuff. Aggregate functions like `COUNT` which re
SELECT users.id, users.name, COUNT(posts.id) AS posts_written
FROM users
JOIN posts ON users.id = posts.user_id
GROUP BY users.id;
GROUP BY users.id, users.name;
```

Note that grouping by `users.name` in addition to `users.id` improves clarity and aligns with best practices by explicitly including all selected non-aggregated columns in the `GROUP BY` clause, though it might not be strictly necessary for most databases.
See [W3Schools' browser-based SQL playground](http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_groupby) for an interactive visual.

The last nifty trick is if you want to only display a subset of your data. In a normal situation, you'd use a `WHERE` clause to narrow it down. But if you've used an aggregate function like `COUNT` (say to get the count of posts written for each user in the example above), `WHERE` won't work anymore. <span id='having-function'>So to conditionally retrieve records based on aggregate functions, you use the `HAVING` function, which is essentially the `WHERE` for aggregates</span>. So say you only want to display users who have written more than 10 posts:
Expand All @@ -112,8 +113,8 @@ The last nifty trick is if you want to only display a subset of your data. In a
SELECT users.id, users.name, COUNT(posts.id) AS posts_written
FROM users
JOIN posts ON users.id = posts.user_id
GROUP BY users.id
HAVING posts_written >= 10;
GROUP BY users.id, users.name
HAVING COUNT(posts.id) >= 10;
```

Try going back to [W3Schools' browser-based SQL playground](http://www.w3schools.com/sql/trysql.asp?filename=trysql_select_groupby) and joining the `Customers` and the `Orders` tables to get the number of orders in each country and adding the line `HAVING COUNT(*) > 10;` after `GROUP BY` (and delete the extra semicolon in the previous line).
Expand Down

0 comments on commit 51b84f8

Please sign in to comment.