Often you need to show a list of database items and certain aggregate numbers about each item. For instance, when you type the title text on Stack Overflow, the Related Questions list appears. The list shows the titles of related entries and the single aggregated number of quantity of responses for each title.
I have a similar problem but needing multiple aggregates. I’d like to display a list of items in any of 3 formats depending on user options:
- My item’s name (15 total, 13 owned by me)
- My item’s name (15 total)
- My item’s name (13 owned by me)
My database is:
- items: itemId, itemName, ownerId
- categories: catId, catName
- map: mapId, itemId, catId
The query below gets: category name, count of item ids per category
SELECT categories.catName, COUNT(map.itemId) AS item_count FROM categories LEFT JOIN map ON categories.catId = map.catId GROUP BY categories.catName
This one gets: category name, count of item ids per category for this owner_id only
SELECT categories.catName, COUNT(map.itemId) AS owner_item_count FROM categories LEFT JOIN map ON categories.catId = map.catId LEFT JOIN items ON items.itemId = map.itemId WHERE owner = @ownerId GROUP BY categories.catId
But how do i get them at the same time in a single query? I.e.: category name, count of item ids per category, count of item ids per category for this owner_id only
Bonus. How can I optionally only retrieve where catId count != 0 for any of these? In trying ‘WHERE item_count <> 0’ I get:
MySQL said: Documentation #1054 - Unknown column 'rid_count' in 'where clause'
Here’s a trick: calculating a
SUM()of values that are known to be either 1 or 0 is equivalent to aCOUNT()of the rows where the value is 1. And you know that a boolean comparison returns 1 or 0 (or NULL).As for the bonus question, you could simply do an inner join instead of an outer join, which would mean only categories with at least one row in
mapwould be returned.Here’s another solution, which is not as efficient but I’ll show it to explain why you got the error:
You can’t use column aliases in the
WHEREclause, because expressions in theWHEREclause are evaluated before the expressions in the select-list. In other words, the values associated with select-list expressions aren’t available yet.You can use column aliases in the
GROUP BY,HAVING, andORDER BYclauses. These clauses are run after all the expressions in the select-list have been evaluated.