Try COUNT(b_table.id) instead; COUNT counts all non-null values encountered, which is why (I am guessing) you were getting 1 for the unmatched free_values; because the unmatched values still have their own values in their rows.

Edit: Also, are's comment and Alim's answer are also correct in that you need to group by free_value. Otherwise, you'll get total rows of the JOIN, and an effectively randomly chosen free_value.