Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by does not show all the rows

I have a table tblPersonaldata and tblStudentsadmitted

tblPersonalData

UID  Name Gender
------------------------ 
 E1   xyz   M
 E2   pqr   M
 E3   mno   M

tblStudentsadmitted

UID   Status  Stage
----------------------
E1     Y        1
E2     Y        2
E3     Y        1

Now I want the data like this:

Gender  Stage1   Stage2
 M        2       1

But in this case I dont get the data for female gender. I want the data for female gender even if it is null

I have tried this:

select 
    case 
        when gender='M' then 'Male' 
        when gender='F' then 'Female' 
    end as Gender,
    sum(case when Stage=1 then 1 else 0) end as Stage1,
    sum(case when Stage=2 then 1 else 0) end as Stage2
from  tblPersonaldata A inner join 
      tblStudentsadmitted B on A.UID=B.UID 
where B.Status='Y'
group by Gender
like image 840
user1274646 Avatar asked Nov 17 '25 10:11

user1274646


2 Answers

SELECT  CASE WHEN a.Gender = 'M' THEN 'Male' ELSE 'FEMALE' END Gender,
        SUM(CASE WHEN Stage = 1 THEN 1 ELSE 0 END) Stage1,
        SUM(CASE WHEN Stage = 2 THEN 1 ELSE 0 END) Stage2
FROM    personal a
        LEFT JOIN studentadmitted b
            ON a.UID = b.UID AND b.Status = 'Y'
GROUP   BY a.Gender
  • SQLFiddle Demo

SELECT  CASE WHEN c.Gender = 'M' THEN 'Male' ELSE 'Female' END Gender,
        SUM(CASE WHEN Stage = 1 THEN 1 ELSE 0 END) Stage1,
        SUM(CASE WHEN Stage = 2 THEN 1 ELSE 0 END) Stage2
FROM    (SELECT 'F' Gender UNION SELECT 'M' Gender) c
        LEFT JOIN personal a
            ON a.Gender = c.Gender
        LEFT JOIN studentadmitted b
            ON a.UID = b.UID AND b.Status = 'Y'
GROUP   BY c.Gender
  • SQLFiddle Demo

OUTPUT

╔════════╦════════╦════════╗
║ GENDER ║ STAGE1 ║ STAGE2 ║
╠════════╬════════╬════════╣
║ Female ║      0 ║      0 ║
║ Male   ║      2 ║      1 ║
╚════════╩════════╩════════╝
like image 197
John Woo Avatar answered Nov 20 '25 06:11

John Woo


In SQL Server, you can use the PIVOT function to generate the result:

select gender,
  Stage1, 
  Stage2
from
(
  select 
    c.gender,
    'Stage'+cast(stage as varchar(10)) Stage
  from (values ('F'),('M')) c (gender)
  left join tblpersonaldata p
    on c.gender = p.gender
  left join tblStudentsadmitted s
    on p.uid = s.uid
    and s.Status='Y'
)src
pivot
(
  count(stage)
  for stage in (Stage1, Stage2)
) piv

See SQL Fiddle with Demo.

Since you are using SQL Server 2008 this query uses the VALUES to generate the list of the genders that you want in the final result set

from (values ('F'),('M')) c (gender)

Then by using a LEFT JOIN on the other tables the final result will return a row for both the M and F values.

This can also be written using a UNION ALL to generate the list of genders:

select gender,
  Stage1, 
  Stage2
from
(
  select 
    c.gender,
    'Stage'+cast(stage as varchar(10)) Stage
  from 
  (
    select 'F' gender union all
    select 'M' gender
  ) c
  left join tblpersonaldata p
    on c.gender = p.gender
  left join tblStudentsadmitted s
    on p.uid = s.uid
    and s.Status='Y'
)src
pivot
(
  count(stage)
  for stage in (Stage1, Stage2)
) piv

See SQL Fiddle with Demo

The result of both is:

| GENDER | STAGE1 | STAGE2 |
----------------------------
|      F |      0 |      0 |
|      M |      2 |      1 |
like image 35
Taryn Avatar answered Nov 20 '25 05:11

Taryn