views:

87

answers:

7

Hey guys, forgive me if this is too simple a question. I basically want a count of the number of males and females in a database. So I know two simple queries will accomplish this, such as:

select count(*) from table where gender='male'
select count(*) from table where gender='female'

However, this seems very inefficient since I know that the queries below are both the same query:

select count(*) from table where gender='female'
select count(*) from table where gender<>'male'

Is there an optimal way to retrieve this information, without having to go through each row in the database twice?

+5  A: 
select sum(case when gender='male' then 1 end) as MaleCount,
    sum(case when gender='female' then 1 end) as FemaleCount
from table
RedFilter
In the case of only 2 possible values such as "male" and "female", the case statement works. However, a more flexible approach when dealing with n possible values is to GROUP by the column containing the values. This way, you don't need to edit your query when new values are added.
XSaint32
+1  A: 

Yes, use a case statement instead.

SELECT
    COUNT(CASE gender WHEN 'male'   then 1 END) AS Males
    COUNT(CASE gender WHEN 'female' then 1 END) AS Females
FROM table
ar
+4  A: 

You may use a group by clause.

select gender, count(gender) from table group by gender;
erwin atuli
That query needs `,gender` in there as well, or else you'll just get unattributed counts.
Andy Lester
thanks for pointing that out, I thought I already my post. Looks the changes weren't saved. I'm updating the query now
erwin atuli
A: 
(select count(*) from table where gender='male')
UNION
(select count(*) from table where gender='female')

first row is males, second row is females...

FatherStorm
You do realize that is still two separate queries?
StingyJack
You do realize that it's the same as the COUNT CASE example above? it's a single statement that is joined into two rows in the same column within MySQL.. the UNION is part of the query.... but instead of returning two columns in 1 row, I'm returning two rows in one column.
FatherStorm
+9  A: 

You could also use a GROUP BY:

SELECT gender, Count(1) as genderCount
FROM   table
GROUP BY gender

This will result in something like this:

gender       genderCount

Male         10

Female       15
XSaint32
@Andy - Thanks ;)
XSaint32
Thank you very much!
ntsue
You're welcome :)
XSaint32
A: 

Well, RedFilter and erwin atuli probably gave the answer to your question, but if you are just concerned about the performance, then you should put an index on the gender column and the performance of those queries should be fine, so you can execute them multiple times.

If you are using oracle, then a Bitmap Index should be used to index that kind of data.

Many databases cache such aggregation results anyway.

Falcon
A: 

@redfilter: if the table contains no entries your query would just return NULL-Values and not 0 (as integer)

hacktick