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;
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)
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.
I have in my database (SQL Server 2008 R2) a table like this:
ID......Team...........Name......Age
102 Barcelona Mike 15
103 Barcelona Peter 10
104 Barcelona Jacke 10
105 Barcelona Jonas 10
106 Real Madrid Michael 20
107 Real Madrid Terry 26
108 Chelsea James 26
109 Chelsea Arthur 23
110 Chelsea Spence 22
How can I loop the field 'Team' and know that, there are records like Barcelona, Real Madrid and Chelsea.
After that I want to calculate the sum of the team player of each team.
For Barcelona: -> 10 + 10 + 10 + 15 = 45
For Real Madrid: -> 20 + 26 = 46
For Chelsea: -> 26 + 23 + 22 = 71
Fill each result in a separate variable.
The whole calculation should be done in a stored procedure.
The second thing, if I have a table like this:
ID......Team...........Name......HeaderGoal......FreeKickGoal
104 Barcelona Mike 2 1
105 Barcelona Peter 1 0
106 Real Madrid Michael 0 1
107 Real Madrid Terry 0 1
108 Chelsea James 0 0
109 Chelsea Arthur 2 3
110 Chelsea Spence 4 0
How can I loop the field 'Team' and know that, there are records like Barcelona, Real Madrid and Chelsea.
After that I want to calculate the sum of all Goals of each team with the goal type HeaderGoal and FreeKickGoal.
Example for
-> Barcelona: 2+1+1 = 4
-> Real Madrid: 1+1 = 2
-> Chelsea: 2 + 3 + 4 = 9
Fill each result in a separate variable.
The whole calculation should be done in a stored procedure.
I hope you can help me!
BK_
If I understood your question correctly it looks like what you want are aggregates for each group, something that is easily accomplished with the GROUP BY clause.
For the first query you would use:
SELECT team, SUM(age) AS 'Sum of the team'
FROM table
GROUP BY team
This will give this result:
Team Sum of the team
-------------------- ---------------
Barcelona 45
Chelsea 71
Real Madrid 46
and for the second:
SELECT team, SUM(headergoal + freekickgoal) AS 'Sum of goals'
FROM table
GROUP BY team
which will give this result:
Team Sum of goals
-------------------- ------------
Barcelona 4
Chelsea 9
Real Madrid 2
In your example data you list the desired result for the first part for Chelsea as 45 but I guess that is just a typo as you omitted one of Chelseas rows in the calculation?
As for turning it into a stored procedure I can just tell you that it's easy and refer you to the documentation as I won't do all the work for you...
Edit: added merge intoas a response to a comment:
To insert the result of the second query into an existing table you can use either a simple INSERT statement like this:
INSERT table_with_team_and_goals
SELECT team, SUM(headergoal + freekickgoal)
FROM table
GROUP BY team
or MERGE INTO which might be better if you intend to run the query many times (the target table will then be updated if the team already exist in it):
MERGE INTO table_with_team_and_goals AS target
USING (SELECT Team, SUM(headergoal + freekickgoal) AS goals FROM table_with_goals GROUP BY team) AS source
ON target.team=source.team
WHEN MATCHED THEN
UPDATE SET goals = source.goals
WHEN NOT MATCHED THEN
INSERT (Team, Goals)
VALUES (source.team, source.goals);
SELECT TEAM , Name, COUNT(TEAM) As GoalsPerTeam, COUNT(NAME) As GoalPerPlayer
FROM TABLE
GROUP BY TEAM , Name
This query will give you tolal goals scored by per player and per team .
-- Sum age by team
SELECT Team, SUM(Age) SumAge
FROM
(
SELECT Id, Team, Name, Age FROM
(
VALUES
(102, 'Barcelona' , 'Mike' , 15),
(103, 'Barcelona' , 'Peter' , 10),
(104, 'Barcelona' , 'Jacke' , 10),
(105, 'Barcelona' , 'Jonas' , 10),
(106, 'Real Madrid', 'Michael', 20),
(107, 'Real Madrid', 'Terry' , 26),
(108, 'Chelsea' , 'James' , 26),
(109, 'Chelsea' , 'Arthur' , 23),
(110, 'Chelsea' , 'Spence' , 22)
) AS X(Id, Team, Name, Age)
) X
GROUP BY Team
-- Sum goals by team
SELECT Team, SUM(HeaderGoal + FreeKickGoal) Goals
FROM
(
SELECT Id, Team, Name, HeaderGoal, FreeKickGoal FROM
(
VALUES
(104, 'Barcelona' , 'Mike' , 2, 1),
(105, 'Barcelona' , 'Peter' , 1, 0),
(106, 'Real Madrid', 'Michael', 0, 1),
(107, 'Real Madrid', 'Terry' , 0, 1),
(108, 'Chelsea' , 'James' , 0, 0),
(109, 'Chelsea' , 'Arthur' , 2, 3),
(110, 'Chelsea' , 'Spence' , 4, 0)
) AS X(Id, Team, Name, HeaderGoal, FreeKickGoal)
) X
GROUP BY Team
course Table
course_code course_name credit_points_reqd
1 Comp Science 300
2 Soft Engineering 300
subject Table
subject_code subject_name credit_points
CS123 C Prog 15
CS124 COBOL 15
enrolment table
student_id student_name course_code subject_code Results
1 Lara Croft 1 CS123 70
1 Lara Croft 1 CS124 50
2 Tom Raider 2 CS123 60
2 Tom Raider 2 CS124 40
3 James Bond 1 CS123 NULL
3 James Bond 1 CS124 40
OUTPUT TABLE
student_name course_name credit_points_obt credit_points_reqd
Lara Croft Comp Science 30 300
Tom Raider Soft Engineering 15 300
I'm currently using TSQL. So here's the situation. I've prepared these tables to get the output like the way it i showed u up there. I need to calculate the credit points obtained. Credit points are achieved if the student receives > 50 for a subject they took. I want to ignore students that has not received any credit points at all (eg, James Bond is ignored as he has not achieved any points yet)
select student_name, course_name,credit_points_obt,credit_points_reqd
FROM enrolment (SELECT student_full_name, SUM(credit_points) AS credit_points_obt
FROM enrolment
GROUP BY student_id),
Totally stuck...I have no idea where to go now.
You can sum conditionally to get points for subject. If none are given result will be null, so you filter out those student/course pairs in having clause.
I've changed > 50 condition to >= 50 because your results contradict your requirements. Also, by the data I'd say that you have omitted student table for brewity, but if you haven't, it is a must.
Live test is # Sql Fiddle.
select enrolment.student_name,
course.course_name,
course.credit_points_reqd,
sum(case when enrolment.results >= 50
then subject.credit_points
end) credit_points_obt
FROM enrolment
inner join course
on enrolment.course_code = course.course_code
inner join subject
on enrolment.subject_code = subject.subject_code
group by enrolment.student_name,
course.course_name,
course.credit_points_reqd
having sum(case when enrolment.results >= 50
then subject.credit_points
end) is not null