Getting Group By Count In Left Outer Join
Sometimes I amazed that I just miss the most obvious solutions. I was running a query that had a left outer join on a list of vendors, joining to orders (purchase orders). I wanted to get the count of orders per vendor, so I was just getting the COUNT(*) of the Group BY.
The problem with this technique is that the COUNT(*) counts the vendor in the left outer join, not just the orders in the right portion of the join. To solve this, I started to do crazy queries involving sub-queries. It was nuts. Then, it dawned on me... I DON'T have to do COUNT(*). I can do counts on specific columns. And hence:
SELECT | |
t.id, | |
t.name, | |
( ISNULL( COUNT(r.id), 0 ) ) AS reward_count, | |
( ISNULL( SUM(r.price), 0 ) ) AS price_sum, | |
( 0 ) AS reward_count_percent, | |
( 0 ) AS price_sum_percent | |
FROM | |
vendor_type t | |
LEFT OUTER JOIN | |
vendor_vendor_type_jn vtjn | |
ON | |
t.id = vtjn.vendor_type_id | |
LEFT OUTER JOIN | |
@reward r | |
ON | |
vtjn.vendor_id = r.vendor_id | |
GROUP BY | |
t.id, | |
t.name |
Want to use code from this post? Check out the license.
Reader Comments
Wouldn't you only have to do the ISNULL for SUM? COUNT (at least on MSSQL) should have a count of 0 (zero) for NULL values.
@Gareth,
You might be correct on that, cause COUNT() should return zero if there are no records. Good call.
Thanks for this... I was also about to embark on a crazy sub-query journey.
thanks for the code.
Thank You!
Hi Thanks for this Code!
LG from Austria
Thanks!
It was had been a while since I last did this.. I forgot that I had to use group by to get all my listings :D
@Blaine,
Glad to help out :)
Thanks this helped a bunch. I was trying to count the comments associated to a topic, and I didn't want to run subqueries. BTW, for MySQL the command is IfNull
Glad I came across your posting because it didn't dawn on me initially to do it this way either. Your post saved me from going down the crazy query road.
Thanks ...
@Mike,
Glad to help.
@Ruddy,
Thanks for the MySQL tip. I used to do only MS SQL, but now, we use mostly MySQL at work, so that helps.
rewrite the given query without using join and group by
select b.title,max(bc.returneddate-bc.checkoutdate) ''most days out'' from bookshelf_checkout bc,bookshelf b where bc.title(+)=b.title group by b.title;
Thanks for the tip - I was stuck on this one too!
@Jeff,
Glad to help.
Thanks for this blog. I was stuck with the COUNT(*) when I really wanted to count only one column. It didn't even click to me until I visit your bolg.
This SQL isn't syntatically correct as ISNULL() only takes 1 parameter. I would suggest something along the lines of:
IF( ISNULL( COUNT(r.id)), 0, COUNT(r.id) ) AS reward_count
@George,
What SQL engine are you using? I definitely ran this code before it was posted and it worked just fine.
It's been a rough four years ago since you've posted this, but it definitely works!
Thanks!
Worked great. Thanks for the tip!
@George,
That worked for me too