Group By results as individual column names - mysql

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;

Related

mysql 8 pivot query should return a non null value

I would like the following pivot query to show value 0 instead of null,
SELECT
pi.employeeId,
pi.Id,
MAX(CASE
WHEN pi.category = 'Repayment' THEN pi.value
WHEN isnull(pi.category) = 1 then 0
-- ELSE 0
END) as 'Repayment',
MAX(CASE
WHEN pi.category = 'Salary' THEN pi.value
ELSE 0
END) as 'Salary',
MAX(CASE
WHEN pi.category = 'Allowance' THEN pi.value
ELSE 0
END) as 'Allowance'
FROM
payData pi
GROUP BY pi.employeeId , pi.Id ;
Output for the above is,
employeeId Id Repayment Salary Allowance
121 2 2000 15000 1000
122 2 null 20000 2000
Employee id 122 does not have a Repayment value so the desired output is,
employeeId Id Repayment Salary Allowance
121 2 2000 15000 1000
122 2 0 20000 2000
dbfiddle
I don't see the need for the second branch of the repayment case. If you want 0 when the category is not available, just else 0:
SELECT
employeeId,
Id,
MAX(CASE WHEN category = 'Repayment' THEN value ELSE 0 END) as Repayment,
MAX(CASE WHEN category = 'Salary' THEN value ELSE 0 END) as Salary,
MAX(CASE WHEN category = 'Allowance' THEN value ELSE 0 END) as Allowance
FROM payData pi
GROUP BY employeeId, Id;
Notes:
Don't use single quotes for identifiers! They should be used for literal strings only, as specified in ANSI SQL and supported in all databases.
You have a mono-table query, so prefixing all column names is not mandatory

MySQL GROUP BY not giving desired result

I have to show summary as number of males, number of females in each unit. Tried the following query:
SELECT
unit,
CASE gender
WHEN 'Male' THEN COUNT(id)
END AS 'male',
CASE
WHEN gender = 'Female' THEN COUNT(id)
END AS 'female'
FROM
admission_info
WHERE
admission_date = '2017-04-15'
GROUP BY gender
Here's the Fiddle which shows the output. But i want it in 1 row where it should show unit name, number of males, number of females.
SELECT unit,
sum(CASE gender WHEN 'Male' THEN 1 else 0 END) AS 'male',
sum(CASE WHEN gender='Female' THEN 1 else 0 END) AS 'female'
FROM admission_info WHERE admission_date='2017-04-15'
group by unit
SELECT unit, gender, count(id) as count
FROM admission_info WHERE admission_date='2017-04-15' GROUP BY unit, gender

i want MySQL query result in same row

SELECT sum(case when (gender)=1 THEN 1 ELSE 0 END),
GROUP_CONCAT(sum(case when (gender)=2 THEN 1 ELSE 0 END) SEPARATOR ' ') as combine
from family_member_tbl
GROUP BY gender
NO, you can't nest grouping function like that. Rather get the sum first and then group_concat() like
select sum_1, sum_2, group_concat(sum_2) as combine
from (
SELECT gender,
sum(case when gender = 1 THEN 1 ELSE 0 END) as sum_1,
sum(case when gender = 2 THEN 1 ELSE 0 END) as sum_2
from family_member_tbl
GROUP BY gender ) xxx
group by gender;

Count SQL Statement Without Create Other View

I have a table name as JOB_Details and the data show as below:
Employee_ID Age Department Gender
001 30yrs IT M
002 34yrs HR F
003 39yrs HR F
004 49yrs Finance M
005 54yrs IT M
006 20yrs HR M
007 24yrs HR F
008 33yrs Finance F
009 29yrs Finance F
010 44yrs IT M
The output i wish to display should be like
Age Department:IT Department:Finance Department:HR Total
Male Female Male Female Male Female
<30yrs 1 0 0 1 1 1 4
30-34yrs 0 0 0 1 0 1 2
35-39yrs 0 0 0 0 0 1 1
40-49yrs 1 0 1 0 0 0 2
50-54yrs 1 0 0 0 0 0 1
Total 3 0 1 2 1 3 10
Based on my knowledge, the only way can be done it is by create another view and group them one by one. But i wish to know is that other way to do it without create a other view? I wish to learn it if anyone have other good suggestion. Thank you very much.
MySQL version. Will not work in SQL Server neither Oracle. SQL Fiddle
select *, IT_Male + IT_Female + Finance_Male + Finance_Female + HR_Male + HR_Female as Total
from (
select
ar.`range` as Age,
count(Department = 'IT' and Gender = 'M' or null) as IT_Male,
count(Department = 'IT' and Gender = 'F' or null) as IT_Female,
count(Department = 'Finance' and Gender = 'M' or null) as Finance_Male,
count(Department = 'Finance' and Gender = 'F' or null) as Finance_Female,
count(Department = 'HR' and Gender = 'M' or null) as HR_Male,
count(Department = 'HR' and Gender = 'F' or null) as HR_Female
from
JOB_Details jd
inner join
age_range ar on jd.Age between ar.bottom and ar.top
group by ar.`range`
order by ar.bottom
) s
union
select
'Total',
count(Department = 'IT' and Gender = 'M' or null),
count(Department = 'IT' and Gender = 'F' or null),
count(Department = 'Finance' and Gender = 'M' or null),
count(Department = 'Finance' and Gender = 'F' or null),
count(Department = 'HR' and Gender = 'M' or null),
count(Department = 'HR' and Gender = 'F' or null),
count(*)
from JOB_Details
Oracle version without external table or view: SQL Fiddle
with age_range as (
select 0 as "bottom", 29 as "top", '<30' as "range" from dual union
select 30, 34, '30-34' from dual union
select 35, 39, '35-59' from dual union
select 40, 49, '40-49' from dual union
select 50, 54, '50-54' from dual
)
select s.*, IT_Male + IT_Female + Finance_Male + Finance_Female + HR_Male + HR_Female as Total
from (
select
ar."range" as Age,
count(case when Department = 'IT' and Gender = 'M' then 1 end) as IT_Male,
count(case when Department = 'IT' and Gender = 'F' then 1 end) as IT_Female,
count(case when Department = 'Finance' and Gender = 'M' then 1 end) as Finance_Male,
count(case when Department = 'Finance' and Gender = 'F' then 1 end) as Finance_Female,
count(case when Department = 'HR' and Gender = 'M' then 1 end) as HR_Male,
count(case when Department = 'HR' and Gender = 'F' then 1 end) as HR_Female
from
JOB_Details jd
inner join
age_range ar on jd.Age between ar."bottom" and ar."top"
group by ar."range", ar."bottom"
order by ar."bottom"
) s
union
select
'Total',
count(case when Department = 'IT' and Gender = 'M' then 1 end),
count(case when Department = 'IT' and Gender = 'F' then 1 end),
count(case when Department = 'Finance' and Gender = 'M' then 1 end),
count(case when Department = 'Finance' and Gender = 'F' then 1 end),
count(case when Department = 'HR' and Gender = 'M' then 1 end),
count(case when Department = 'HR' and Gender = 'F' then 1 end),
count(*)
from JOB_Details
SELECT
CASE WHEN Age < 30 THEN '<30'
WHEN 30 <= Age AND Age < 34 THEN '30-34'
...
END as Age,
SUM(CASE WHEN Department = 'IT' AND Gender = 'M' THEN 1 ELSE 0) END AS IT_M,
SUM(CASE WHEN Department = 'IT' AND Gender = 'F' THEN 1 ELSE 0) END AS IT_F,
...
FROM JOB_DETAILS
GROUP BY
CASE WHEN Age < 30 THEN '<30y'
WHEN 30 <= Age AND Age < 34 THEN '30-34'
...
END

MYSQL count function merging

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 ...