Renaming result categories in SQL - sql

I have the following query which outputs the number and percentage of members whose Salutation is Mr / Ms.
I want to rename the results to say 'Male' instead of 'Mr' and Female instead of 'Ms'.
It's probably a fairly simple CASE thing, but can't get it to work...
SELECT AspNetUsers.Salutation AS Sex, COUNT(AspNetUsers.Salutation) as Total,
CAST(ROUND((COUNT(AspNetUsers.Salutation)* 100.0 / (SELECT COUNT(*) FROM Member, AspNetUsers WHERE Member.AspNetUserId = AspNetUsers.Id)),1) AS NUMERIC(36,1)) AS Percentage
FROM Member, AspNetUsers
WHERE Member.AspNetUserId=AspNetUsers.Id
GROUP BY Salutation

You're absolutely correct that it's a simple case expression that is needed, but you also need to group by the same case expression.
SELECT
CASE
WHEN AspNetUsers.Salutation = 'Mr' THEN 'Male'
WHEN AspNetUsers.Salutation = 'Ms' THEN 'Female'
ELSE 'Other' -- this is of course optional
END AS Sex,
COUNT(AspNetUsers.Salutation) as Total,
CAST(ROUND((COUNT(AspNetUsers.Salutation)* 100.0 / (SELECT COUNT(*) FROM Member JOIN AspNetUsers ON Member.AspNetUserId = AspNetUsers.Id)),1) AS NUMERIC(36,1)) AS Percentage
FROM Member
JOIN AspNetUsers ON Member.AspNetUserId = AspNetUsers.Id
GROUP BY
CASE
WHEN AspNetUsers.Salutation = 'Mr' THEN 'Male'
WHEN AspNetUsers.Salutation = 'Ms' THEN 'Female'
ELSE 'Other' -- this is of course optional
END;
The query could probably be improved by using a common table expression to not have to repeat the case expression, and a windowed count instead of a subquery, but I'll leave that to you.

Related

Having trouble with the subquery in this code

I'm trying to run this code for an assignment for a class I've got. The "x" at the end of my subquery keeps on giving me errors and I can't wrap my head around why this is.
The goal of this assignment is to count (by age group) the number of reports that Carditis was a symptom after receiving a COVID shot.
Thanks in advance
Select agegroup, sum(case when died= 'Y' then 1 else 0 end) as Deaths
From (Select *,
Case
when age<=2 then 'infant'
when age<18 then 'juvenile'
when age<35 then 'adult'
when age<65 then 'old adult'
when age>=65 then 'senior'
else 'unknown' end as agegroup
from dbo.symptoms as s
join dbo.vaersvax as v on s.vaers_id=v.vaers_id
join dbo.patient as p on s.vaers_id=p.vaers_id
where v.vax_type='COVID19' and OneVax='Y' and symptom='Carditis'
) as x
Group By agegroup
Order By avg(age)
As #Schmocken already said, you can't perform a SELECT FROM a subquery that returns more than one column with the same name. As I suppose from your external query, this would do the job for you:
Select agegroup, sum(case when died= 'Y' then 1 else 0 end) as Deaths
From (Select died, age,
Case
when age<=2 then 'infant'
when age<18 then 'juvenile'
when age<35 then 'adult'
when age<65 then 'old adult'
when age>=65 then 'senior'
else 'unknown' end as agegroup
from dbo.symptoms as s
join dbo.vaersvax as v on s.vaers_id=v.vaers_id
join dbo.patient as p on s.vaers_id=p.vaers_id
where v.vax_type='COVID19' and OneVax='Y' and symptom='Carditis'
) as x
Group By agegroup
Order By avg(age)
By using Select * you have specified the same column name to be returned more than once.
As an example, you are returning both s.vaers_id and v.vaers_id, which are the same. This is not allowed; a subquery must return a unique set of column names.
You could return s.* successfully, but not all columns from all tables.

Is it possible to combine these two sql statements into one statement using group by?

select client_type, count(gender) as num_males
from clients
where gender = 'Male'
group by client_type;
select client_type, count(gender) as num_females
from clients
where gender = 'Female'
group by client_type;
The following SQL statements show the number of males by client type, then the number of females by client type. I would like an SQL statement to show the following columns: client_type, count(gender = 'Male'), count(gender = 'Female'). Is it possible to do this?
You could count a couple of case expressions:
SELECT client_type,
COUNT(CASE gender WHEN 'Male' THEN 1 END) AS num_males,
COUNT(CASE gender WHEN 'Female' THEN 1 END) AS num_females
FROM clients
GROUP BY client_type;

Merge Rows COUNTS in SQL

Currently I have data in sql and need to merge the counts from rows.
My code is:
WHERE lower(GENDER) IS NOT NULL
GROUP BY lower(GENDER)
And it's out putting a table like:
Gender Count
female 100
f 101
male 102
m 103
unknown 104
Is there a way to combine the counts from female and f and then similarly from male and m?
Use a case expression:
select
case lower(gender)
when 'f' then 'female'
when 'm' then 'male'
else lower(gender)
end new_gender,
count(*) cnt
from mytable
where gender is not null
group by case lower(gender)
when 'f' then 'female'
when 'm' then 'male'
else lower(gender)
end
Note that you don't need lower() to check if gender is null.
Some databases support positional parameters in the group by clause, so you can just do:
group by 1
Other databases support re-using aliases defined in the select clause:
group by new_gender
Sure you just need to somehow list how that's going to happen. This can be done using a function or a case statement.
A case statement is a fine solution for a one off query, but I'd recommend a conversion table or a function if you're going to be spreading this across multiple queries.
select
case
when lower(gender) = 'f' or lower(gender) = 'female'
then 'female'
when lower(gender) = 'm' or lower(gender) = 'male'
then 'male'
end as cleanded_gender
, count(*) as gender_count
from
...
where
gender is not null
group by
case
when lower(gender) = 'f' or lower(gender) = 'female'
then 'female'
when lower(gender) = 'm' or lower(gender) = 'male'
then 'male'
end
Depending on your RDBM you can take the substring of Gender, only the first char,
and it will group on "f", "m", "u"... not nice, but it will work

Compare the count of data in same column in same table and display the larger value

I wanted to a count of the same field for different values for example:
user{user_id, gender}
Gender can have obviously male or female :)
i want to get count for all the males and females i.e.
COUNT(male) COUNT(female)
4 16
but i'm confused because they come from the same gender column thanks
ALSO, I Want the result to only display the higher count. Like
COUNT(female)
16
Try the following using case statement.
select
sum(case when gender = 'male' then 1 else 0 end) as total_male,
sum(case when gender = 'female' then 1 else 0 end) as total_female
from user
If you are using MySQL then use following
select
sum(gender = 'male') as total_male,
sum(gender = 'female') as total_female
from user
If you are using PostgreSQL then use filter
select
count(1) filter (where gender = 'male') as total_male,
count(1) filter (where gender = 'female') as total_female
from user
You can achieve your final result by following query. here is the demo.
select
case
when total_male < total_female then total_female
else total_male
end as total_count
from
(
select
count(1) filter (where gender = 'male') as total_male,
count(1) filter (where gender = 'female') as total_female
from users
) t

How can you have two COUNT queries GROUPED BY the same column in SQL?

I have two table named, one named Employees, and one named Shop. The Employees table holds the gender of all employees, while the Shop table has the name of the store that each employee works at.
I need to count the number of both male and female employees and group them by the store they work at. For example, the wanted outcome would look like this:
FemaleEmployees MaleEmployees Store
1 2 Ed's Hardware
3 4 Grocery store
So far I have this:
SELECT COUNT(Gender) AS FemaleEmployees, StoreName AS Store
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
Where Gender = 'F'
GROUP BY StoreName;
SELECT COUNT(Gender) AS MaleEmployees, StoreName AS Store
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
Where Gender = 'M'
GROUP BY StoreName;
Which obviously gives the needed answer in two select queries, though I need it to be in a single query. I just need help on getting the two into a single query format.
I have experimented with using two subquerys, but so far nothing has worked. I know how to get the answer, just not in the needed format. Would appreciate it if someone could help me figure this one out.
You can do this
SELECT SUM(CASE WHEN Gender='F' THEN 1 ELSE 0 END) As FemaleEmployees,
SUM(CASE WHEN Gender='M' THEN 1 ELSE 0 END) As MaleEmployees,
storeName
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
GROUP BY storeName
Another way using COUNT
SELECT COUNT(CASE WHEN Gender='F' THEN 1 END) As FemaleEmployees,
COUNT(CASE WHEN Gender='M' THEN 1 END) As MaleEmployees,
StoreName AS Store
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
Where Gender in ( 'F','M' )
GROUP BY StoreName;
Filter the Gender in Where clause to make the query little efficient..
you need to use "case" statement to differentiate between the cases, like this:
SELECT SUM (SELECT CASE WHEN GENDER = 'M' THEN 1 ELSE 0 END) as MaleCount, SUM (SELECT CASE WHEN GENDER = 'F' THEN 1 ELSE 0 END) AS FemaleCount, Storename AS Store
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
GROUP BY StoreName;
most of above answer always get count of gender 1 or 0 only...not get actual count..
SO GETTING ACTUAL COUNT YOU CAN DO THIS..
SELECT (CASE WHEN GENDER = 'M' THEN COUNT(GENDER) ELSE 0 END) as MaleCount,
(CASE WHEN GENDER = 'F' THEN COUNT(GENDER) ELSE 0 END) AS FemaleCount,
Storename AS Store
FROM Employees
JOIN Store
ON Employees.EmployeeID = Store.EmployeeID
GROUP BY StoreName;