Assuming you want to only count products created in the "last month" (counting back from "now"):
SELECT store_id
FROM product
WHERE created_at > now() - interval '1 month'
GROUP BY store_id
ORDER BY count(*) DESC;
I didn't even include the store
table. You only get the store_id
and no stores without any qualifying products. This is as fast as it gets.
An index on created_at
would be instrumental. A multicolumn index on (created_at, store_id)
would optimize further. More expensive, more specialized, but faster for the query at hand. In pg 9.2+ you could get index-only scans out of it.
To include columns of the store
table as well as stores with 0 qualifying products:
SELECT s.*
FROM store s
LEFT JOIN (
SELECT store_id, count(*) AS ct_prod
FROM product
WHERE created_at > now() - interval '1 month'
GROUP BY store_id
) p ON s.store_id = p.store_id
ORDER BY p.ct_prod DESC NULL LAST, s.store_id;
NULLS LAST
is essential to sort rows without any matches last.
I added s.store_id
as arbitrary tie breaker to get a consistent sort order for stores with the same ct_prod
.