tags:

views:

58

answers:

3

I am trying to find all deals information along with how many comments they have received. My query

select deals.*,
       count(comments.comments_id) as counts
from deals 
left join comments on comments.deal_id=deals.deal_id 
    where cancelled='N'

But now it only shows the deals that have at least one comment. What is the problem?

A: 

Try changing left join to right outer join

manyxcxi
Left join cannot be inner. It's always OUTER.
a1ex07
+2  A: 

You missed GROUP BY

select deals.*, count(comments.comments_id) as counts 
from deals 
left join comments on comments.deal_id=deals.deal_id 
where cancelled='N'
GROUP BY deals.deal_id
a1ex07
Works. Thanks a lot. But why need GROUP BY
David
Aggregate function (`count` in this case) is applied to a group. The group is defined in GROUP BY clause. As far as I remember, standard SQL requires that all nonaggregated columns in SELECT to appear in GROUP BY ( in your case you would need to add GROUP BY deals.deal_id, deals.field2,... deals.field_N). However, Mysql extension ignores this requirement (there is a good reason for that in some cases). If you used a different SQL server, you'd likely get an error instead of unexpected results.
a1ex07
group by aggregates the count to each deal - otherwise you would get a grand total
Randy
I wince because this query still relies on MySQL's hidden columns in the group by: http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html
OMG Ponies
A: 

Is 'cancelled' a column of comments? If so, you need to move "cancelled='N'" from the WHERE clause to the ON clause (from deals left join comments on comments.deal_id = deals.deal_id AND comments.cancelled='N') or do the filtering in an inline view (from deals left join (select * from comments where cancelled='N') comments on comments.deal_id = deals.deal_id) since filtering it in the where clause will drop all rows where cancelled is null.

araqnid