Count for both Male and Female for a specific ID - sql

I have a database of animals with their sex and the cage no they are kept in.
I want to count the number of females and males in each cage
e.g.
Animal CageNo Sex
Dog2 01 M
Dog1 01 F
Cat1 03 F
SELECT cageno, COUNT(sex) AS 'Female'
FROM animal
WHERE sex='F'
GROUP BY cageno
I want one column with the CageNo, count of Females in cage, count of Males in cage
E.g.
CageNo Female Male
01 1 1
03 1 0

You can use conditional aggregation:
SELECT cageno,
SUM(CASE WHEN sex = 'F' THEN 1 ELSE 0 END) AS Female,
SUM(CASE WHEN sex = 'M' THEN 1 ELSE 0 END) AS Male
FROM animal
GROUP BY cageno;
You should only use single quotes for string and date constants. You do not need to escape these names. If you do, use the appropriate escape character for your database (double quotes, back ticks, or square braces).

Related

Generate a score for several row and certain values and sum all

I have a table as below
CustomerNumber CustomerName Type Gender Age Nationality Residance
584 John Denver Retail Male 50 English Domestic
137 Jennifer Hazel Retail Female 34 Jamaican Abroad
547 Daniel Gorbo Retail Male 78 French Domestic
I need to generate a total score depends on Type, Gender, Age, Nationality and Residance values. For example,
For gender, male value generates "1", female "0"
For age, if it is greater than 65 generates "3" else "0"
For Nationality if non-english than generate 2 else 0
Final table should look like this:
CustomerNumber CustomerName Type Gender Age Nationality Residance RiskScore
584 John Denver Retail Male 50 English Domestic 1
137 Jennifer Hazel Retail Female 34 Jamaican Abroad 2
547 Daniel Gorbo Retail Male 78 French Domestic 6
I tried to add sum and 'case when' to main code however i got the error of 'need group by function'
sum( case when gender = 'Male' then 1
when age>65 then 3
when nationality = 'Abroad' then 2 else 0 end ) as RiskScore
Any help would be appreciated..
select *,
(case when gender = 'Male' then 1 else 0 end +
case when age>65 then 3 else 0 end +
case when nationality <> 'English'
then 2 else 0 end) as risk_score from my_table;
Just change your condition accordingly
If I understand the question correctly, you do not need an aggregation. Use an addition and CASE expression to calculate the risk score:
SELECT
v.*,
RiskScore = (
CASE WHEN Gender = 'Male' THEN 1 ELSE 0 END +
CASE WHEN Age > 65 THEN 3 ELSE 0 END +
CASE WHEN Nationality <> 'English' THEN 2 ELSE 0 END
)
FROM (VALUES
(584, 'John Denver', 'Retail', 'Male', 50, 'French', 'Domestic'),
(137, 'Jennifer Hazel', 'Retail', 'Female', 34, 'Jamaican', 'Abroad'),
(547, 'Daniel Gorbo', 'Retail', 'Male', 78, 'English', 'Domestic')
) v (CustomerNumber, CustomerName, Type, Gender, Age, Nationality, Residance)
Result:
CustomerNumber CustomerName Type Gender Age Nationality Residance RiskScore
584 John Denver Retail Male 50 French Domestic 3
137 Jennifer Hazel Retail Female 34 Jamaican Abroad 2
547 Daniel Gorbo Retail Male 78 English Domestic 4
As per the logic shared by you, below query should give the correct result using CASE and adding the value without group by:
Demo
SELECT A.*, COALESCE(case when gender = 'Male' then 1 ELSE 0 END , 0) +
COALESCE(CASE WHEN age>65 then 3 ELSE 0 END , 0) +
COALESCE( CASE when Nationality <> 'English' then 2 else 0 end, 0 ) as RiskScore
FROM TABLE1 A;

sql select and replace

I have a query that will show all the client information, and there is a column called sex, which 1 is female, 0 is male. How can I do another select on this result, that turn all the female record, turn the 1 to 100, male to 101? ( 1 and 0 in the first query, they are bit, in the second they are nvarchar) (Mssql)
select * from tblClientInfo
001 Derrick 0
002 Mary 1
then, turn it to
001 Derrick 100
002 Mary 101
You can use case:
select (case when male = 0 then '100' else '101' end)

have trouble when table.field_name is needed in two columns based on different values

I have a person table that has a sex field and a few other fields. Looks like this
firstname lastname sex birthday
--------- -------- --- ---------
john doe 0 1960-01-25
jane doe 1 1990-02-01
john smith 0 1995-03-15
mary smith 1 1990-01-16
so sex = 0 means male sex = 1 means female.
I'd like to see this as a result assuming the current_date as 2014-02-04
Age Female Male
--- ------ ----
18 0 1
24 2 0
54 0 1
I have this
SELECT count(*) AS Female,
cast(DATEDIFF(CURRENT_DATE,person.birthday)/(365.256366) AS SIGNED) AS Age
FROM person
WHERE person.sex=1
GROUP BY Age
which gives me the above result without the Male col. I can do a similar one for Male and Age but no Female. How do merge the two to get all three columns?
You can do that as a conditional SUM:
SELECT SUM(CASE WHEN person.sex=1 THEN 1 ELSE 0 END) AS Female,
SUM(CASE WHEN person.sex=0 THEN 1 ELSE 0 END) AS Male,
cast(DATEDIFF(CURRENT_DATE,person.birthday)/(365.256366) AS SIGNED) AS Age
FROM person
GROUP BY Age
BTW your "age" calculation will be close but will not be right when you're on someone's exact birthday day.

SQL script to change the structure of the table

I am working on a SQL database (Microsoft SQL Server 2008)
I have a table like this
Country Gender Number
---------+---------------+-----------+
Russia Male 50000
Russia Female 40000
Russia Unknown 30000
India Male 45678
India Female 21354
China Male 37878
China Female 45686
China Unknown 24534
France Male 45378
France Female 49783
Is there an sql select script that can return a table like this:
Country Male Female Unknown
---------+---------------+-----------+-----------------+
Russia 50000 40000 30000
India 45678 21354 0
China 37878 45686 24534
France 45378 49783 0
Please note that some countries do not have "Unkown" data so in this case it should be 0.
I tried a couple of things but I did not get any close results. Thanks for any help.
You can use pivot operator for such kind of queries:
select Country,
IsNull([Male], 0) Male,
IsNull([Female], 0) Female,
IsNull([Unknown], 0) Unknown
from TableName t
pivot (sum(Number) for Gender in ([Male], [Female], [Unknown])) p
or ... pivot max(Number) for ... if you know that (Country, Gender) combination is unique in original data.
you can also use this query
select
T.Country,
max(case when T.Gender = 'Male' then T.Number else 0 end) as Male,
max(case when T.Gender = 'Female' then T.Number else 0 end) as Female,
max(case when T.Gender = 'Unknown' then T.Number else 0 end) as Unknown
from Table1 as T
group by T.Country
sql fiddle demo

Get Names from Values in a select statement + Sql server 2005

Here is my query
Select Gender from Table
The result pane shows
1
1
1
2
2
But i want the results to be
Male
Male
Male
Female
Female
The names Male and Female wont be present in my database.... I want to just hardcode the names based on values from the select statement....
try
Select case WHEN Gender=1 THEN 'Male' ELSE 'Female' end Gender from Table