标准分计算两种实现方式,计算公式见百度百科。
1 直接借助sql,写一个方法
/**
* 计算生成标准分
* @return
*/
public int doGenerateStandScore() {
StringBuilder sql = new StringBuilder();
sql.append(" SELECT ");
sql.append(" avg(er.total_score) avgScore, ");
sql.append(" STD(er.total_score) standardDeviation, ");
sql.append(" 39/((max(total_score) - avg(er.total_score))/STD(er.total_score)- ");
sql.append(" (50 - avg(er.total_score))/STD(er.total_score)) coefficient, ");
sql.append(" 60 - (50 - avg(er.total_score))/STD(er.total_score)*39/((max(total_score) - ");
sql.append(" avg(er.total_score))/STD(er.total_score) - ");
sql.append(" (50 - avg(er.total_score))/STD(er.total_score)) referPoints ");
sql.append(" FROM ");
sql.append(" exam_reserve er ");
sql.append(" INNER JOIN exam_batch bat ON bat.id = er.fk_exam_batch_id ");
sql.append(" INNER JOIN enum_const active ON active.id = bat.flag_active ");
sql.append(" WHERE ");
sql.append(" active. CODE = '1' ");
sql.append(" AND er.total_score IS NOT NULL ");
// 平均分,方差,扩大系数,基准分
Map<String, Object> resultMap = myGeneralDao.getOneMapBySQL(sql.toString());
if (MapUtils.isEmpty(resultMap)) {
throw new ServiceException("没有需要合成标准分的数据");
}
BigDecimal avgScore = new BigDecimal(String.valueOf(resultMap.get("avgScore")));
BigDecimal standardDeviation = new BigDecimal(String.valueOf(resultMap.get("standardDeviation")));
BigDecimal coefficient = new BigDecimal(String.valueOf(resultMap.get("coefficient")));
BigDecimal referPoints = new BigDecimal(String.valueOf(resultMap.get("referPoints")));
sql.delete(0, sql.length());
sql.append(" UPDATE exam_reserve er ");
sql.append(" INNER JOIN exam_batch bat ON bat.id = er.fk_exam_batch_id ");
sql.append(" INNER JOIN enum_const active ON active.id = bat.flag_active ");
sql.append(" SET er.standard_score = round((er.total_score - ?)/? * ? + ?) ");
sql.append(" WHERE ");
sql.append(" active. CODE = '1' ");
sql.append(" AND er.total_score IS NOT NULL ");
return myGeneralDao.executeBySQL(sql.toString(), avgScore, standardDeviation, coefficient, referPoints);
}
2 java代码方式写工具方法。
package plugins;
import com.ss.excel.db.DB;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;
/**
* 计算标准分 (此处严格来讲应该将double改成BigDecimal类型)
*
* @author ss
*/
public class StandardScoreUtils {
public static void main(String[] args) throws SQLException {
List<Double> rawScores = DB.query(sql);// sql为查询的结果集
double avgScore = calculateScoreMean(rawScores);
System.out.println("平均分----" + avgScore);
double standardDeviation = calculateSTD(rawScores, avgScore);
System.out.println("标准差----" + standardDeviation);
System.out.println("****************************************************************************");
for (Double rawScore : rawScores) {
double standardScore = calculateStandardScore(rawScore, standardDeviation, avgScore);
double result = new BigDecimal(standardScore).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
System.out.println("原始分:" + rawScore + "---- 标准分四舍五入:" + result + "----标准分:" + standardScore);
}
}
/**
* 计算平均分
* @param rawScores
* @return
*/
public static double calculateScoreMean(List<Double> rawScores) {
double scoreAll = 0.0;
for (Double score : rawScores) {
scoreAll += score;
}
return scoreAll/rawScores.size();
}
/**
* 计算标准差
* @param rawScores
* @param avgScore
* @return
*/
public static double calculateSTD(List<Double> rawScores, double avgScore) {
double allSquare = 0.0;
for (Double rawScore : rawScores) {
allSquare += (rawScore - avgScore) * (rawScore - avgScore);
}
return Math.sqrt(allSquare/rawScores.size());
}
/**
* 计算标准分
* @param score
* @param standardDeviation
* @param avgScore
* @return
*/
public static double calculateStandardScore(double score, double standardDeviation, double avgScore) {
double standardScore = (score - avgScore)/standardDeviation;
return standardScore;
}
}