Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count distinct values in MySQL without folding NULL values

I have table a with two fields: id (PK) and f.

Consider following records:

id | f
1  | NULL
2  | 'foo'
3  | 'bar'
4  | NULL
5  | 'foo'
6  | 'baz'

I want to retrieve and count all the records having distinct f values including every record WHERE f IS NULL. Given this criteria, the query should return every record except #5, because the same value is already included in the set, and the total count would be 5.

The query I'm using to retrieve all records looks like this:

SELECT CASE WHEN EXISTS (SELECT id FROM a a2 WHERE a2.f = a.f AND a.id < a2.id) THEN 1 END AS not_distinct FROM a HAVING not_distinct IS NULL

If this query could be improved, I'd welcome any feedback. Anyway, the main problem is counting. Obviously adding a COUNT(*) will not help here and I'm totally lost how to count the records after the filtering.

like image 243
package Avatar asked Nov 28 '12 12:11

package


People also ask

Does COUNT distinct ignore nulls?

If the COUNT DISTINCT function encounters NULL values, it ignores them unless every value in the specified column is NULL. If every column value is NULL, the COUNT DISTINCT function returns zero (0).

Does COUNT distinct include NULL MySQL?

DISTINCT returns a row for a single NULL as a distinct value, but COUNT DISTINCT does not count NULL. The COUNT(DISTINCT BY(FavoriteColors) %ID) value is the same as the row count, because the BY clause does count a single NULL as a distinct value.

Does COUNT distinct include nulls?

In the following output, we get only 2 rows. SQL COUNT Distinct does not eliminate duplicate and NULL values from the result set. Let's look at another example.

Does COUNT ignore NULL values MySQL?

The MySQL COUNT() function provides a number of records in the result set from a table when an SQL SELECT statement is executed. This function does not count the NULL values.


1 Answers

There's a pretty simple approach that might work for you:

select count(distinct ifnull(f, id))
from a

Note that this query assumes that f values are never id values, and based on sample data and experience this is reasonable.

Edited:

I thought about it and there's an even simpler approach:

select count(distinct f) + sum(f is null) from a;

which you can see running on sqlfiddle

This works because distinct throws away nulls, and sum(condition) counts the number of times condition is true because in mysql true is 1 and false is 0.

like image 129
Bohemian Avatar answered Sep 20 '22 12:09

Bohemian