【问题标题】:How to calculate a GPA in MySql如何在 MySql 中计算 GPA
【发布时间】:2019-05-25 10:10:03
【问题描述】:

查询应输出学生的姓名和 GPA。

给出了下表:

部分:

CREATE TABLE `Section` (
  `ID` int(11) NOT NULL,
  `Semester` varchar(45) DEFAULT NULL,
  `Room` varchar(45) DEFAULT NULL,
  `Instructor_ID` int(11) NOT NULL,
  `Course_ID` int(11) NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `fk_Section_Instructor_idx` (`Instructor_ID`),
  KEY `fk_Section_Course1_idx` (`Course_ID`),
  CONSTRAINT `fk_Section_Course1` FOREIGN KEY (`Course_ID`) REFERENCES `Course` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_Section_Instructor` FOREIGN KEY (`Instructor_ID`) REFERENCES `Instructor` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


INSERT INTO `Section` VALUES (1,'Fa17','828',1,1),(2,'Fa17','828',2,3),(3,'Fa17','829',1,4),(4,'Fa17','829',4,5),(5,'Sp18','828',1,1),(6,'Sp18','829',1,2),(7,'Sp18','828',3,4),(8,'Sp18','828',4,5);

课程:

DROP TABLE IF EXISTS `Course`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `Course` (
  `ID` int(11) NOT NULL,
  `Title` varchar(45) DEFAULT NULL,
  `Description` text,
  `Units` int(11) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Course` VALUES (1,'CIS-15','Cloud Programming in Python',4),(2,'CIS-54','Relational Databases',4),(3,'CIS-81','Introduction to Networking',4),(4,'CIS-75','Introduction to Computer Security',3),(5,'CIS-90','Introduction to Linux',3);

注册:

 CREATE TABLE `Registration` (
  `Section_ID` int(11) NOT NULL,
  `Student_ID` int(11) NOT NULL,
  `Grade` int(11) DEFAULT NULL,
  PRIMARY KEY (`Section_ID`,`Student_ID`),
  KEY `fk_Section_has_Student_Student1_idx` (`Student_ID`),
  KEY `fk_Section_has_Student_Section1_idx` (`Section_ID`),
  CONSTRAINT `fk_Section_has_Student_Section1` FOREIGN KEY (`Section_ID`) REFERENCES `Section` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_Section_has_Student_Student1` FOREIGN KEY (`Student_ID`) REFERENCES `Student` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Registration` VALUES (1,1,4),(1,2,4),(2,2,3),(3,3,2),(4,1,3),(4,3,3),(5,3,NULL),(5,4,NULL),(6,1,NULL),(6,2,NULL),(7,1,NULL),(7,4,NULL),(8,2,NULL),(8,3,NULL);

学生:

CREATE TABLE `Student` (
  `ID` int(11) NOT NULL,
  `Name` varchar(45) DEFAULT NULL,
  `Email` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Student` VALUES (1,'Steve Inskeep','steve@xyz.edu'),(2,'Rene Montaign','rene@xyz.edu'),(3,'David Green','david@xyz.edu'),(4,'Rachel Martin','rachel@xyz.edu');

我尝试了这段代码,然后得到了无意义的输出。我很迷茫

SELECT student.Name, (sum( registration.grade * course.units) /
    sum(course.units)
   ) as GPA FROM registration 

   join student on registration.student_ID = student.id join section on  section.ID = registration.section_ID
   join course on section.course_ID = course.ID
   group by registration.student_ID  ;

GPA 似乎是错误的,因为

@Barbaros Özhan 的建议以及我自己的类似解决方案返回的结果是:

'1', '史蒂夫因斯基普', '1.7857'

作为返回的第一行。

但通过观察注册表,学生 #1 的 GPA 显然不是 1.7857。

编辑:戈登·林诺夫回答:

 select student.Name,
       (sum( registration.grade * course.units) /
        sum( case when registration.grade is not null then course.units end )
       ) as GPA
from registration  join 
     student 
     on registration.student_ID = student.id join
     section 
     on section.ID = registration.section_ID join
     course 
     on section.course_ID = course.ID
group by student.ID  ;

【问题讨论】:

  • 成绩是否必须按课程单元加权?
  • @Nick 未指定。
  • @RichardMichaelLaboe 。 . .你说的废话输出是什么意思?查询看起来没问题。
  • @GordonLinoff 我刚刚在我的编辑中解释了它。
  • 请参阅Why should I provide an MCVE for what seems to me to be a very simple SQL query? 以提供示例数据和预期结果。此外,您还必须解释 GPA 是什么,我假设它是平均绩点?...

标签: mysql sql


【解决方案1】:

问题是你有 NULL grades 。 . .但是您正在计算部分,因此这些部分被视为零。

对您的计算稍作调整即可解决此问题:

select s.Name,
       (sum( r.grade * c.units) /
        sum( case when r.grade is not null then c.units end )
       ) as GPA
from registration r join 
     student s
     on r.student_ID = s.id join
     section se
     on se.ID = r.section_ID join
     course c
     on se.course_ID = c.ID
group by s.student_ID  ;

【讨论】:

  • 哇,甜!根本不知道如何处理那些空值或大小写!谢谢!我将您的代码略微编辑为:选择 student.Name, (sum(registration.grade * course.units) / sum(case when registration.grade 不为 null then course.units end) ) 作为 GPA 从注册加入学生注册。 student_ID = student.id 加入 section.ID 上的部分 = registration.section_ID 加入 section.course_ID 上的课程 = course.ID group by student.ID ;但是,是的,这完全有效
  • @RichardMichaelLaboe 。 . .你有理由不接受这个答案吗?这是指出您计算中的问题以及如何解决它的第一个答案。
  • 对不起!我是新手,我想我可以将不止一个人标记为已回答。兆!已应用修正
【解决方案2】:

您可以按如下方式加入您的表格:

select s.ID, s.Name,  
       sum( r.grade * c.Units ) / sum(c.Units) as GPA
  from student s
  left join registration r on r.Student_ID = s.ID
  left join section sc on sc.ID = r.Section_ID
  left join course c on c.ID = sc.Course_ID 
 group by s.ID, s.Name 

Demo

【讨论】:

  • 感谢您的帮助。正如我刚刚在编辑中解释的那样,您提供的解决方案似乎并不准确。我也不知道为什么。
【解决方案3】:

鉴于学生在每个部分中获得一个成绩,我认为您的查询中不需要SectionCourse 表(尽管没有看到示例数据,很难确定)。这应该有效:

SELECT s.Name, COALESCE(SUM(r.Grade) / COUNT(r.Grade), 0) AS GPA
FROM student s
JOIN registration r ON r.Student_ID = s.ID
GROUP BY s.Name

输出

Name            GPA
David Green     2.5
Rachel Martin   0
Rene Montaign   3.5
Steve Inskeep   3.5

Demo on dbfiddle

如果您需要根据课程单元对成绩进行加权,那么您需要将成绩乘以单元相加,然后除以单元的总和,注意求和有有效成绩的课程单元:

SELECT s.Name, 
       ROUND(COALESCE(SUM(r.Grade * c.Units) / SUM(CASE WHEN r.Grade IS NOT NULL THEN c.Units ELSE 0 END), 0), 2) AS GPA
FROM Student s
JOIN Registration r ON r.Student_ID = s.ID
JOIN Section x ON x.ID = r.Section_ID
JOIN Course c ON c.ID = x.Course_ID
GROUP BY s.Name;

输出:

Name            GPA
David Green     2.5
Rachel Martin   0
Rene Montaign   3.5
Steve Inskeep   3.57

Demo on dbfiddle

【讨论】:

  • 谢谢!这也回答了这个问题。我以前没有听说过合并功能。 @GordonLinoff 有一个解决方案,不需要使用 round 或 coalesce 函数并返回相同的输出。什么时候需要这些?
  • @RichardMichaelLaboe 我的解决方案也不需要要求使用COALESCEROUNDCOALESCE 用于将 Rachel MartinNULL 值转换为 0,因此如果您很高兴拥有 NULL 值,您可以删除它,ROUND 是因为在加权 GPA 查询,Steve Inskeep 的结果将显示为 3.5714,我认为将其设置为 3.57 会更有用,因为 GPA 通常仅表示为小数点后 2 位。要查看没有COALESCEROUND 的结果,请参阅:db-fiddle.com/f/rFqju5Nr8Hz7eP1XrwUmpt/3
  • 非常酷!非常感谢您向我解释这一点!这些都是很好的观点。
  • @RichardMichaelLaboe 不用担心,很乐意提供帮助。
【解决方案4】:

您正在从注册表中加入学生 ID,但您尚未从注册表中选择它以加入它。尝试将学生 ID 添加到注册表中的选择中。

然后您正在将课程表加入节表,但节表尚未加入。操作无效,需要先加入板块才能从板块加入课程。

可能还有其他麻烦,但从这里开始。

【讨论】:

    猜你喜欢
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多