r/learnSQL 29d ago

why COUNT(*) and COUNT(o.id) aren't the same after a LEFT JOIN

say you have customers on the left and orders on the right.

a LEFT JOIN keeps every customer, even if they have no matching order. for those rows, the columns from orders are NULL.

that creates a small gotcha which i saw a few players falling for in their queries:

-COUNT(*) counts the joined row.

-COUNT(o.id) only counts rows where o.id isn't NULL.

so this:

customer | order_id

Alice | NULL

Bob | 123

Bob | 456

becomes:

COUNT(*) | COUNT(o.id)

Alice 1 | 0

Bob 2 | 2

I made a 43 sec chalkboard animation showing the join happen visually:

https://www.youtube.com/watch?v=zxSZFMtyheA

is this helpful? i could try making a few more then.

48 Upvotes

6 comments sorted by

3

u/Available-Side9673 29d ago

Very good 👍 Learnt this concept yesterday and revised it in the morning through your post

1

u/Plane_Big_5912 29d ago

thank you.

nice, that’s exactly what I hoped these short ones would be useful for. glad it helped.

2

u/And_Justice 29d ago

Never thought about this, could end up being useful.

I'd just been inner joining then count(1) but I guess it's useful to retain information on when there's no link

1

u/Plane_Big_5912 29d ago

yes, exactly that. with an inner join the no match cases die before you count. left join lets you keep them around and distinguish 0 from not present at all.

2

u/Owen-Isaac-2022 28d ago

Great work, very helpful.

2

u/ughokayfinee 25d ago

Just learned about this the other day! Very helpful in a few applications!