SQL script to change the structure of the table - sql

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

Related

SQL Queries - Count total of rows with Case when statement

I will like to count to get the correct number of rows when the [Location] column match a certain value.
Below is my table:
Student
Marks
Location
Date
Kenn
66
UK
09-01-2022
Kenn
89
UK
09-01-2022
Kenn
77
Canada
09-01-2022
Below SQL queries is what I have tried:
SELECT [Student]
,COUNT(CASE WHEN [Location] = 'UK' THEN [Marks] ELSE 0 END) AS UK
,COUNT(CASE WHEN [Location] = 'Canada' THEN [Marks] ELSE 0 END) AS Canada
FROM table_name
GROUP BY [Student]
But the output is
Student
UK
Canada
Kenn
3
3
What I expected to see is:
Student
UK
Canada
Kenn
2
1
Please advise if anything wrong with my SQL queries?
Thank you!!
Use sum instead
SELECT [Student]
,SUM(CASE WHEN [Location] = 'UK' THEN 1 ELSE 0 END) AS UK
,SUM(CASE WHEN [Device] = 'Canada' THEN 1 ELSE 0 END) AS Canada
FROM table_name
GROUP BY [Student]

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;

Challenge with Not Equal to operator

I have a problem to solve. I would like to get the countries where the gender not equal to Female from the following table using only the where clause. I don't want to use the sub query like: select country from table where country not in (select country from table where gender='Female')
Any ideas ?
ID Name Gender Country
1 Jhon Male USA
2 Katie Female USA
3 Steave Male UK
4 Gerry Female UK
5 Brad Male AUS
Regards,
Chandra.
Use not exists
select t.*
from table t
where not exists (select 1
from table
where Country = t.Country and
Gender = 'Female'
);
You can also use group by like that :
select Country
from table t
group by Country
having sum(case when Gender = 'Female' then 1 else 0 end) = 0;
You could avoid subquery and get full rows by using:
SELECT TOP 1 WITH TIES *
FROM tab
ORDER BY SUM(CASE WHEN Gender='Female' THEN 1 ELSE 0 END)
OVER(PARTITION BY Country);
DBFiddle Demo - SQL Server
You can do:
select country
from t
except
select country
from t
where gender = 'Female';
As a set operator, except removes duplicates.
Maybe I got your question wrong but why you don't use:
SELECT country FROM table WHERE gender NOT IN('Female')
Or is it a sub query?

Oracle SQL Query Tuning for output

I have an output such as below
select City, Gender, count(*) from tablename group by City, Gender ;
City Gender count(*)
Chennai Male 640000
Chennai Female 623000
Blore Male 500000
Blore Female 600000
Pune Male 700000
Pune Female 700000
But I am looking for getting the same output as like below
City Male Female
Chennai 640000 623000
Blore 500000 600000
Pune 700000 700000
Appreciate your help.
Thanks
You need conditional sum for this
select
City,
sum(case when Gender = 'Male' then 1 else 0 end) as Male,
sum(case when Gender = 'Female' then 1 else 0 end) as Female
from tablename group by City
Here is short code
select city,sum(male),sum(female) from tablename group by city;

Required single SQL query

I have a table with the name empdetail and columns:
Id Name Gender
1 ABC Male
2 XYZ Female
3 PQR Male
I want to change Gender of each emp from Male to Female and from Female to Male with single query
Result should be this:
1 ABC Female
2 XYZ Male
3 PQR Female
You Just need to use the CASE Statement
update <table>
set Gender= case when Gender='Male' then 'Female'
when Gender='Female' then 'Male'
end
SQL fiddle demo
select id,name,
(case when gender='Male'
then 'Female'
else 'Male'
end) as 'Gender'
from table
-------------------
update table set gender=(case when gender='Male'
then 'Female' else 'Male' end)