NetBeans项目

最后一个赢博体育

我们的测验系统项目的最后一步是构造一个赢博体育程序来显示学生参加的测验的结果。

我想显示一些信息,比如某个学生在某个测验中答对了多少道题。为了能够回答这些问题,我们将需要利用SQL语言中的一些更高级的特性。

设置默认模式

如果你想运行下面的例子,你应该在MySQL中安装测验数据库。(由于您在分配时使用了这个数据库,因此您应该已经安装了它。)

此外,您还需要确保将测验数据库设置为工作台中的默认数据库。为此,在Schema视图中右键单击测验数据库,并选择命令Set as Default Schema。

使响应表更有用

当学生提交测试问题的答案时,我们将把他们的答案存储在答案表中。这个表格的结构有一个小问题,虽然有一列是问题编号,但没有一列是测验编号。这是有意为之,因为这些信息可以在问题表中找到。如果你知道问题的编号,你可以去问题表查找测验的编号。这种数据库结构符合关系数据库的主要目标之一,即不存在冗余信息。

即便如此,这种安排也会造成一些明显的问题。假设我们只想显示某个特定测验的回答。现在还没有办法在响应表上运行该查询,因为该表没有用于测验编号的列。

这个问题的解决方案是使用SQL语言中称为连接的强大特性。这个特性允许我们通过合并两个或多个独立的表来从现有表中合成新表。

下面是一个SQL连接语句的示例。

从回答中选择*。Id = responses.question

这将生成一个新的更大的表,该表是将响应表与问题表合并而成的。连接通过从第一个表中获取赢博体育可能的行并将其与第二个表中的赢博体育可能行合并来合成行。大多数新行都没有意义,因此我们还需要通过添加on子句来限制生成的行集,该子句告诉我们第一个表中的哪些行要与第二个表中的哪些行合并。在这种情况下,明显的规则是将第一个表中引用特定问题的行与第二个表中引用相同问题的行进行匹配。

连接的另一个典型问题是生成的表有太多的列。更糟糕的是,有时还会出现多个列共享相同的名称,但显示不同的信息。下面是一个更新语句的示例,它修复了这两个问题。

选择反应。我,学生,回应。问题,测验,回答,回答,从回答中纠正问题。Id = responses.question

在这里,我使用了一个表名和一个列名的组合来指示我想要显示哪个id列以及我想要显示哪个问题列。

创建视图

我刚才构造的SQL代码向我们展示了关于学生回答的方便的摘要信息。这些信息非常方便,因此我们可能希望以更简单的方式轻松访问这些摘要信息。为此,我们将使用SQL语句来创建视图。

要在MySQL工作台中创建视图,我们右键单击数据库结构视图中的Views部分,然后选择New view…命令。这将打开一个屏幕,我们可以在其中定义新视图。

在该屏幕中,我们可以输入以下内容:

创建视图‘results’作为选择响应。我,学生,回应。问题,测验,回答,回答,从回答中纠正问题。Id = responses.question

然后单击Apply按钮来创建视图。(我已经在示例数据库中完成了此操作,因此您不需要执行此步骤。)

一旦创建了视图,我们就可以像查询其他表一样查询它。

查询查询结果

获取摘要信息

完成测验评分后,我们将希望显示各种汇总信息,例如每个学生答对了多少道题,以及每个问题有多少学生答对了。

在SQL中提取摘要信息的关键是在select语句中使用GROUP BY子句。正如命令的名称所暗示的那样,如果行具有共同的特征,则该子句将行放入组中。将行分组之后,可以对组赢博体育各种汇总操作,如sum()、min()和count()。

下面是GROUP BY子句与sum()函数结合使用的示例,用于报告每个学生答对了多少道题。

选择学生,从测验= 5的结果中取(正确)作为分数

另一个例子是打印一份报告,显示每个特定问题有多少学生答对了。

选择问题,将(正确的)作为正确的答案从结果中选出,其中测验= 5按问题分组

总结赢博体育

现在我们可以为我们的测验系统构建最后一个赢博体育程序了。这个赢博体育程序将允许用户生成几个有用的摘要报告。

该赢博体育程序可以生成两种不同的报告。Quiz Summary报告允许用户生成一个报告,显示赢博体育学生在特定测验中的表现。Student Summary报告允许用户为特定学生生成报告,其中显示该学生回答了多少问题以及该学生在数据库中的每个测试中答对了多少问题。

下面是其中一个报告的例子:我们要求系统为算术测验生成一个测验报告。

这份报告相当粗糙。在运行相关查询之后,我们从返回的结果中构造一个文本块,然后简单地将该文本放在TextArea中供用户查看。

两个查询

为了生成这些报告,我必须构造一对SQL语句。下面是这些语句的代码。首先,生成学生报告的语句:

选择测验,将(正确)求和为正确,从学生=?的结果中计算(问题)为回答分组测验

生成测试报告的语句更详细一些:

选择姓名,sum(正确)作为正确,count(问题)作为回答,从results.student=students的结果中加入学生。where quiz=?按学生分组

在这个例子中,我需要做的一个额外步骤与结果视图的工作方式有关。这种观点通过学生证号码来识别学生。由于我们希望摘要显示学生的姓名,因此我必须执行一个涉及结果视图和学生表的连接来访问这些姓名。