Sql server 如何使用tsql计算学生的分数?
我有这样一个场景Sql server 如何使用tsql计算学生的分数?,sql-server,tsql,Sql Server,Tsql,我有这样一个场景 Studentid|Subject1|Subject2|Subject3|Subject4|Subject5|Grade 1 | 1 | 1 | 1 | 1 | 1 | 2 | 1 | 2 | 2 | 2 | 3 | .....etc 表中显示了学生id及其在每个科目中的排名。我想根据以下条件更新“成绩”列 1如果所有科目排名均为1,则
Studentid|Subject1|Subject2|Subject3|Subject4|Subject5|Grade
1 | 1 | 1 | 1 | 1 | 1 |
2 | 1 | 2 | 2 | 2 | 3 |
.....etc
表中显示了学生id及其在每个科目中的排名。我想根据以下条件更新“成绩”列
1如果所有科目排名均为1,则毕业生应为A
2如果任何3个等级为1,而其他2个科目的等级为2,则为B
3如果任何3个等级为2,而其他2个受试者的等级为3,则c
诸如此类的情况可能会出现,所以我只想知道解决方法
是否可以编写单个查询?您可以取消PIVOT表以计算等级:
;with
Subject1 as (
select Studentid, 1 as SubjectCode, Subject1 as subjectResult
from your_table
),
Subject2 as (
select Studentid, 2 as SubjectCode, Subject2 as subjectResult
from your_table
),
...
Subject5 as (
select Studentid, 5 as SubjectCode, Subject5 as subjectResult
from your_table
),
subjects as (
select * from Subject1 union all
select * from Subject2 union all
...
select * from Subject5
)
select
Studentid, sum( subjectResult )
from
subjects
group by
Studentid
请注意,在最后一个select中,您可以使用case语句计算等级。
此外,您还可以升级“等级”列,只需稍作更改:
...),
subjects as (
select * from Subject1 union all
select * from Subject2 union all
...
select * from Subject5
),
grades as (
select
Studentid, sum( subjectResult ) as grade
from
subjects
group by
Studentid
)
update t set grade = grades.grade
from your_table t
inner join grades on t.Studentid = grades.Studentid
同意所有其他评论,这是一种糟糕的数据存储方式。但是,如果你陷入困境,必须与之合作,那么类似的事情可能会奏效:
UPDATE StudentsTable
SET StudentsTable.Grade = CASE
WHEN Tally.Total < 8
THEN 'A'
WHEN Tally.Total < 13
THEN 'B'
ELSE 'C'
END
FROM StudentsTable AS St
JOIN (
SELECT StudentID,
Subject1 + Subject2 + Subject3 + Subject4 + Subject5 AS [Total]
FROM StudentsTable
) AS Tally
ON St.StudentID = Tally.StudentID
根据需要修改CASE语句。它不漂亮,但应该能起作用。我用了UNPIVOT:
CREATE TABLE s
(
Studentid INT ,
Subject1 INT ,
Subject2 INT ,
Subject3 INT ,
Subject4 INT ,
Subject5 INT ,
Grade CHAR(1)
)
INSERT INTO [s] VALUES
( 1 , 1 , 1 , 1 , 1 , 1 , ''),
( 2 , 1 , 2 , 2 , 2 , 3 , '')
WITH cte AS (
SELECT u.StudentID, AVG(u.[g]) AS [grade]
from (SELECT * FROM [s]) AS [f]
UNPIVOT (g FOR [SUBJECT] IN (Subject1, Subject2, Subject3, Subject4, Subject5)) AS [u]
GROUP BY u.StudentID
)
UPDATE [s]
SET [Grade] = CASE
WHEN c.[grade] <=1 THEN 'A'
WHEN c.[grade] <=2 THEN 'B'
WHEN c.[grade] <=3 THEN 'C'
WHEN c.[grade] <=4 THEN 'D'
ELSE 'F'
END
FROM [cte] AS [c]
INNER JOIN [dbo].[s]
ON [c].StudentId = [s].[Studentid]
正如其他人所说,你的评分标准有点模棱两可,但我猜了一下。如果不同,请根据您的需要进行更改。您可以规范化您的模式吗?当然,这种类型的信息不应该与subct1、subject2等列放在一个表中。这样做比使用规范化结构要困难得多。我们需要更好的要求。如果我有5个2呢?4秒和1秒?4 1和1 2?你不能只说等,也不能只给出可能的5+中的3个的要求排列。有没有一个数学方程式是你想忽略的?同意,使用RedFilter-根据你的表格布局,你想做的事情是非常复杂的。规范化您的表将使其更简单。表1可能由StudentID和Grade列组成,而表2可能由StudentID、SubjectNumber和Ranki组成。如果我按照David的观点规范化这个表,我如何编写查询?当然,这是基于分数的最基本求和来获得分数。如果涉及到更复杂的逻辑,您将需要修改,并且根据复杂性,上述内容可能无法使用