【发布时间】:2016-08-18 16:09:42
【问题描述】:
在我构建的一个考试应用程序中,我还没有想出一种方法来提出一个 SQL 语句来使这项任务成为可能。我国的评分系统只要求计算7个科目。在这些科目中,所有语言都是必修的(在图片演示中标记为 lang)。计算了 2 种最好的科学(标记为 sci)。一个人类(标记为嗡嗡声)。第 7 个科目可能是技术科目(标记为 tech)、科学或人文学科,取决于哪个科目得分最高。例如,给定表中的学生将计算 MAT、ENG、KISW、PHY、CHEM、HIST 和 BST 的分数。我使用数组编写了 PHP 代码,它占用了太多的内存和时间,这让我担心它会使服务器停止运行。看看下面的代码,
function calculatePointsB($adm,$term,$class,$year,$exam){
global $db;
$points=array(
"A"=>12,
"A-"=>11,
"B+"=>10,
"B"=>9,
"B-"=>8,
"C+"=>7,
"C"=>6,
"C-"=>5,
"D+"=>4,
"D"=>3,
"D-"=>2,
"E"=>1
);
$choices=array();
$countable=array();
$monitor=array();
$grades=array();
$common_query_all=$db->prepare("SELECT marks,subject,sub_cat FROM averaged_marks WHERE adm_no=? AND sub_cat=? AND term=? AND class=? AND year=?");
$common_query_sp=$db->prepare("SELECT marks,subject,sub_cat FROM exmarks WHERE adm_no=? AND sub_cat=? AND term=? AND class=? AND year=? AND e_type=?");
//languages first
$langs=array();
if($exam=="All") {
$getlang = $common_query_all;
$getlang->execute(array($adm, "lang", $term, $class, $year));
}else{
$getlang = $common_query_sp;
$getlang->execute(array($adm, "lang", $term, $class, $year,$exam));
}
while($rst=$getlang->fetch(PDO::FETCH_ASSOC)){
if($rst['marks']!=null) {
$langs[$rst['subject']] = $rst['marks'];
$grades[$rst['subject']]=$points[$rst['grade']];
$countable[$rst['subject']] = $rst['marks'];
array_push($monitor,$rst['sub_cat']);
}else continue;
} unset($rst);
//sciences
$sciences=array();
if($exam=="All") {
$getlang = $common_query_all;
$getlang->execute(array($adm, "sci", $term, $class, $year));
}else{
$getlang = $common_query_sp;
$getlang->execute(array($adm, "sci", $term, $class, $year,$exam));
}
while($rst=$getlang->fetch(PDO::FETCH_ASSOC)){
if($rst['marks']!=null) {
$sciences[$rst['subject']] = $rst['marks'];
array_push($monitor,$rst['sub_cat']);
}else continue;
}unset($rst);
arsort($sciences);
//humanities
$humanities=array();
if($exam=="All") {
$getlang = $common_query_all;
$getlang->execute(array($adm, "hum", $term, $class, $year));
}else{
$getlang = $common_query_sp;
$getlang->execute(array($adm, "hum", $term, $class, $year,$exam));
}
while($rst=$getlang->fetch(PDO::FETCH_ASSOC)){
if($rst['marks']!=null) {
$humanities[$rst['subject']] = $rst['marks'];
array_push($monitor,$rst['sub_cat']);
}else continue;
}unset($rst);
arsort($humanities);
//technicals
$technic=array();
if($exam=="All") {
$getlang = $common_query_all;
$getlang->execute(array($adm, "tech", $term, $class, $year));
}else{
$getlang = $common_query_sp;
$getlang->execute(array($adm, "tech", $term, $class, $year,$exam));
}
while($rst=$getlang->fetch(PDO::FETCH_ASSOC)){
if($rst['marks']!=null) {
$technic[$rst['subject']] = $rst['marks'];
$choices[$rst['subject']] = $rst['marks'];
}else continue;
}unset($rst);
arsort($technic);
//add optional subjects to choices array
$iteration=0;
foreach($humanities as $sub => $value){
$iteration++;
if($iteration >1 && $iteration <= 3){
$choices[$sub]=$value;
}elseif($iteration==1){
$countable[$sub]=$value;
if($exam=="All") {
$grades[$sub] = $points[getgradeinSub($adm, $sub, $term, $class, $year)];
}else{
$grades[$sub] = $points[getgradeinSpSub($adm, $sub, $term, $class, $year,$exam)];
}
}
}unset($humanities);
$iteration=0;
foreach($sciences as $sub => $value){
$iteration++;
if($iteration > 2 && $iteration <= 3){
$choices[$sub]=$value;
}elseif($iteration<=2){
$countable[$sub]=$value;
if($exam=="All") {
$grades[$sub] = $points[getgradeinSub($adm, $sub, $term, $class, $year)];
}else{
$grades[$sub] = $points[getgradeinSpSub($adm, $sub, $term, $class, $year,$exam)];
}
}
}unset($sciences);
arsort($choices);
//get required and view the required number
//count number of keys
$count_compasory=array_count_values($monitor);
if($count_compasory['lang']==3 && $count_compasory['sci']>=2 && $count_compasory['hum']>=1){
$remaining=7-count($countable);
$iteration=0;
foreach($choices as $sub => $value){
$iteration++;
if($iteration <= $remaining){
$countable[$sub]=$value;
if($exam=="All") {
$grades[$sub] = $points[getgradeinSub($adm, $sub, $term, $class, $year)];
}else{
$grades[$sub] = $points[getgradeinSpSub($adm, $sub, $term, $class, $year,$exam)];
}
}
}
unset($choices);
unset($countable);
unset($monitor);
unset($langs);
unset($sciences);
unset($humanities);
unset($points);
return array_sum($grades);
}
else unset($choices);
unset($countable);
unset($monitor);
unset($langs);
unset($sciences);
unset($humanities);
unset($grades);
unset($points);
return null;}
一个好的程序员会认为这是一些不好的做法。有没有办法为此编写 SQL 语句?找到问题的解决方案将是一个突破。下面附上一张桌子的图片。
【问题讨论】:
-
为我们提供一个 sqlfiddle (sqlfiddle.com) 和一些数据(一个学生的)将大大有助于回答这个问题。在我看来,这应该可以通过一个选择查询和同一张表上的几个内部连接来解决
-
您的 DBMS 是什么?如果它支持像
ROW_NUMBER这样的分析函数,应该是一个简单的任务 -
@Jester,这里是 SQL 小提琴sqlfiddle.com/#!9/b80692
-
@dnoeth,我正在使用 mysql
-
@m69,我改了。我希望它适合。谢谢你的建议:)