MYSQL count function merging - mysql

In my database table I have two columns that hold either 0 or 1.
I have type and Gender, where type means 0 => teacher and 1 => student and for gender: 0 => male and 1 => female.
How can I write a single sql query to get number of teachers, students, males and females?
Right now I have:
select COUNT(type) as teachers from my_table where type = 0; // Teachers
select COUNT(type) as students from my_table where type = 1; // Students
select COUNT(gender) as males from my_table where type = 0; // Males
select COUNT(gender) as females from my_table where type = 1; // Females
Can it be done in one query? If so, how?

You can use CASE for that using SUM function:
SELECT SUM(CASE type WHEN 1 THEN 1 ELSE 0 END) AS students,
SUM(CASE type WHEN 0 THEN 1 ELSE 0 END) AS teachers,
SUM(CASE gender WHEN 1 THEN 1 ELSE 0 END) AS females,
SUM(CASE gender WHEN 0 THEN 1 ELSE 0 END) AS males
FROM my_table;
You can also use COUNT function instead of SUM like this:
SELECT COUNT(CASE type WHEN 1 THEN 1 ELSE NULL END) AS students,
COUNT(CASE type WHEN 0 THEN 1 ELSE NULL END) AS teachers,
COUNT(CASE gender WHEN 1 THEN 1 ELSE NULL END) AS females,
COUNT(CASE gender WHEN 0 THEN 1 ELSE NULL END) AS males
FROM my_table;
See this SQLFiddle

This way you can do it in a single query. If you have only two types of data in your table then you don't need to specify IN conditions in WHERE clause:
SELECT SUM(IF(type = 1, 1, 0)) as students,
SUM(IF(type = 0, 1, 0)) as teachers,
SUM(IF(gender = 1, 1, 0)) as females,
SUM(IF(gender = 0, 1, 0)) as males
FROM my_table
WHERE type IN(0,1)
AND gender IN(0,1);

You could achive this using subqueries.
SELECT COUNT(type) AS students,
(SELECT COUNT(type) FROM my_table WHERE type = 0) As teachers,
(SELECT COUNT(gender) FROM my_table WHERE gender = 1) AS females,
(SELECT COUNT(gender) FROM my_table WHERE gender = 0) AS males
FROM my_table WHERE type = 1;

Yes, you can. Did you try taking each of your SQL statements and putting them together?
SQL1 as fld1, SQL2 as fld2, someOtherFieldsIfNeeded FROM ...

Related

RETURN the amount of males and the amount of females in 1 table using MySQL

I need to RETURN the amount of males and the amount of females in 1 table using MySQL. I have created a query that return a tables with males and females rows, but my column is not being populated. its results =0;
Here is my query. I get the table but it doesn't get populated
SELECT COUNT(gender) AS 'Female', COUNT(gender) AS 'Male'
FROM customers
WHERE gender = 'female' AND 'male';
Any Suggestions,
This should work:
SELECT
SUM(IF(gender = 'female', 1, 0)) AS 'Female',
SUM(IF(gender = 'male', 1, 0)) AS 'Male'
FROM customers
The IF gets you a value of 1 or 0 depending on whether the gender is female (resp. male) or not, and then you just sum up those zeros and ones to get the overall count.
You can do the CASE statement too:
SELECT
SUM(CASE WHEN gender = 'female' THEN 1 ELSE 0 END) AS 'Female',
SUM(CASE WHEN gender = 'male' THEN 1 ELSE 0 END) AS 'Male'
FROM customers
Since MySQL equates true with 1 and false with 0 you can use a shorter version:
SELECT
SUM(gender = 'female') AS `Female`,
SUM(gender = 'male') AS `Male`
FROM customers
SQL FIDDLE

Sum record between two dates for different users in mysql query Issue

I have two tables lead and lead_details. There is a field status. If status=1 is open, status=2 is close and status=3 is not specified.
I want to find sum of all Open,close and not specified for each user/agent.
Here is what I tried but it give me wrong data
select agent_id,
type,
status,
created_date,
category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,
l.type,
ld.category_id,
l.status,
l.created_date,
count(*) as val
from crm_leads l,
crm_leads_details ld
where l.id=ld.lead_id AND
status in (2, 1, 3)
GROUP BY status, agent_id
) t
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2'
GROUP BY agent_id
You need to put the WHERE created_date clause in the subquery.
select agent_id,type,status,created_date,category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,l.type,ld.category_id,l.status,l.created_date,
count(*) as val from crm_leads l JOIN crm_leads_details ld
ON l.id=ld.lead_id
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2' AND status in (2, 1, 3)
GROUP BY status, agent_id ) t
GROUP BY agent_id
Note that the created_date in the result will just be a randomly selected date in the period for each agent.

Group By results as individual column names

How to get the groupby result as column names
if staff table is there when we use
select count(*) from staff group by gender; gives me as
but i need them as columns Male | Female | None
select sum(case when gender = 'Male' then 1 else 0 end) as 'Male',
sum(case when gender = 'Female' then 1 else 0 end) as 'Female',
sum(case when gender not in ('Male','Female') or gender is null then 1 else 0 end) as 'None'
from staff;

get count of two table fields in one query

I am trying to get the count of females and males in the gender field of a table.
Is there a way to get the count of each in one query?
Something like:
select * from table count(where gender = 'm') as total_males, count(where gender = 'f') as total_females;
or will it require two queries?
select count(*) from table where gender = 'm';
select count(*) from table where gender = 'f';
This is basically a PIVOT. MySQL does not have a pivot so you can use an aggregate function with a CASE statement to perform this:
select
sum(case when gender = 'm' then 1 else 0 end) Total_Male,
sum(case when gender = 'f' then 1 else 0 end) Total_Female
from yourtable
See SQL Fiddle with Demo
Or using COUNT:
select
count(case when gender = 'm' then 1 else null end) Total_Male,
count(case when gender = 'f' then 1 else null end) Total_Female
from yourtable;
See SQL Fiddle with Demo
Something like this will work:
SELECT SUM(IF(t.gender='m',1,0)) AS total_males
, SUM(IF(t.gender='f',1,0)) AS total_females
FROM mytable t
The "trick" here is that we are using a conditional test to return either a 0 or a 1 for each row, and then adding up the 0's and 1's. To make this a little more clear, I am using the SUM aggregate function rather than COUNT, although COUNT could be used just as easily, though we'd need to return a NULL in place of the zero.
SELECT COUNT(IF(t.gender='m',1,NULL)) AS total_males
, COUNT(IF(t.gender='f',1,NULL)) AS total_females
FROM mytable t
Consider that the two expressions in the SELECT list of this query:
SELECT COUNT(1)
, SUM(1)
FROM mytable t
Will return the same value.
If you want to avoid the MySQL IF function, this can also be done using the ANSI SQL CASE expression:
SELECT SUM( CASE WHEN t.gender = 'm' THEN 1 ELSE 0 END )) AS total_males
, SUM( CASE WHEN t.gender = 'f' THEN 1 ELSE 0 END )) AS total_females
FROM mytable t
select sum(case when gender='m' then 1 else null end) as total_males, sum(case when gender='f' then 1 else null end) as total_females from ...
Should work just fine!
If your only issue is to avoid two queries, you can always write two queries as subselects of one query.
Select (select 1 from dual) as one, (select 2 from dual) as two from dual
This would work for your scenario, too.

In 1 query: 2 results, using 2 conditions

I have table with columns type(0 or 1), amount(int)
I need query what returns 2 params: sum amount for type = 1 and sum amount for type = 0
2 queries:
SELECT SUM(amount) AS income FROM table WHERE type = 0;
SELECT SUM(amount) AS expense FROM table WHERE type = 1;
But can i return these params using only 1 query?
SELECT SUM(amount), IF(type=0, 'income', 'expense') AS type
FROM table
GROUP BY type
SELECT sum(case when type = 0
then amount
else 0
end) AS income,
sum(case when type = 1
then amount
else 0
end) AS expense
FROM table
Demo