배경
왕중2초등학교 | 128.00 | 202302 | |
---|---|---|---|
시에 춘화 | 136.00 | 202302 | |
Feng Shijie | 129.00 | 202302 | |
Ma Gongcheng | 130.00 | 202302 | |
Wei Pianpian | 136.00 | ||
rank() over() 구현을 생각하면 쉽습니다. | over()는 Rank(),density_rank(), row_number()와 함께 사용할 수 있는 분석 함수입니다. | 사용 구문은 다음과 같습니다. | 설명: partition by는 결과 집합을 그룹화하는 데 사용됩니다. 지정하지 않으면 전체 결과 집합을 그룹으로 처리합니다. |
rank() 함수는 주로 정렬에 사용되며 정렬된 데이터와 병렬 데이터에 동일한 시퀀스 번호를 부여하고 병렬의 순위를 지웁니다. | dense_rank()는 Rank()와 동일한 기능을 가지고 있지만, 동점이 차지한 순위는 지워지지 않는다는 차이점이 있습니다. |
순위 결과 결과는 1,2,2,4density_rank이고 결과는 1,2,2,3 row_number이고 결과는 1,2,3,4입니다.
실제 응용 프로그램에서는 다음에서 액세스하는 데이터가 있습니다. 다른 외부 시스템과 데이터 양이 크지 않은 경우에는 Java 코드를 사용하여 그룹 순위 기능을 구현하는 것이 더 편리합니다. destailed 디자인 및 구현 정의 정의 클래스 주문 classpublic class OrderBy { private String orderByEL; /** * 是否升序 */ private boolean ascend; public OrderBy(){ //默认升序 this.ascend = true; } public String orderByEL(){ return this.orderByEL; } public OrderBy orderByEL(String orderByEL){ this.orderByEL = orderByEL; return this; } public OrderBy ascend(boolean ascend){ this.ascend = ascend; return this; } public boolean ascend(){ return this.ascend; } }
이 클래스는 다음 속성을 정의합니다. 메소드는 다음과 같이 정의됩니다.
<T> void rankOver(List<T> dataList, String[] partitionByFields, List<OrderBy> orderByList, String resultField, int rankType);
이 메소드는 5개의 입력 매개변수를 제공합니다:
partitionByFields 그룹화된 필드 배열
resultField 필드 순위 결과가 저장됨
2: 동점을 고려하고 순위는 동점이 차지하도록 둡니다(순위 결과는 1,2,2, 4)
이 메서드의 구체적인 구현은 다음과 같습니다
public static <T> void rankOver(List<T> dataList, String[] partitionByFields, List<OrderBy> orderByList, String resultField, int rankType) { if (CollectionUtils.isEmpty(orderByList)) { return; } //STEP_01 剔除掉不参与排名的数据 List<T> tempList = new ArrayList<>(); for (T data : dataList) { boolean part = true; for (OrderBy rptOrderBy : orderByList) { Object o1 = executeSpEL(rptOrderBy.orderByEL(), data); if (o1 == null) { //参与排序的值为null的话则不参与排名 part = false; break; } } if (part) { tempList.add(data); } } if (CollectionUtils.isEmpty(tempList)) { return; } //STEP_02 分组 Map<String, List<T>> groupMap = group(tempList, null, partitionByFields); for (List<T> groupDataList : groupMap.values()) { order(orderByList, groupDataList); if (rankType == 1) { int rank = 1; for (T temp : groupDataList) { setFieldValue(temp, resultField, rank); rank++; } } else { int prevRank = Integer.MIN_VALUE; int size = groupDataList.size(); for (int i = 0; i < size; i++) { T current = groupDataList.get(i); if (i == 0) { //第一名 setFieldValue(current, resultField, 1); prevRank = 1; } else { T prev = groupDataList.get(i - 1); boolean sameRankWithPrev = true;//并列排名 for (OrderBy rptOrderBy : orderByList) { Object o1 = executeSpEL(rptOrderBy.orderByEL(), current); Object o2 = executeSpEL(rptOrderBy.orderByEL(), prev); if (!o1.equals(o2)) { sameRankWithPrev = false; break; } } if (sameRankWithPrev) { setFieldValue(current, resultField, getFieldValue(prev, resultField)); if (rankType == 2) { ++prevRank; } } else { setFieldValue(current, resultField, ++prevRank); } } } } } }
정의 학생 수업:
public class Student { private String batch; private String banji; private String name; private Double yuwen; //extra private Integer rank1; private Integer rank2; public Student(String batch, String banji, String name, Double yuwen) { this.batch = batch; this.banji = banji; this.name = name; this.yuwen = yuwen; } }
public List<Student> getDataList() { List<Student> dataList = new ArrayList<>(); dataList.add(new Student("202302", "三年一班", "张小明", 130.0)); dataList.add(new Student("202302", "三年一班", "王二小", 128.0)); dataList.add(new Student("202302", "三年一班", "谢春花", 136.0)); dataList.add(new Student("202302", "三年二班", "冯世杰", 129.0)); dataList.add(new Student("202302", "三年二班", "马功成", 130.0)); dataList.add(new Student("202302", "三年二班", "魏翩翩", 136.0)); return dataList; }
학생들의 중국어 점수의 학급 순위와 학년 순위를 구합니다. 순위는 동점을 제외하고 묶는 방식을 기반으로 합니다.
List<Student> dataList = getDataList(); List<OrderBy> orderByList = new ArrayList<>(); orderByList.add(new OrderBy().orderByEL("yuwen").ascend(false)); //获取全校排名 DataProcessUtil.rankOver(dataList, new String[]{"batch"}, orderByList, "rank1", 2); //获取班级排名 DataProcessUtil.rankOver(dataList, new String[]{"batch", "banji"}, orderByList, "rank2", 2); log("语文单科成绩排名情况如下:"); Map<String, List<Student>> groupMap = DataProcessUtil.group(dataList, null, new String[]{"batch"}); for (Map.Entry<String, List<Student>> entry : groupMap.entrySet()) { log("考试批次:" + entry.getKey()); for (Student s : entry.getValue()) { log(String.format("班级:%s 学生:%s 语文成绩:%s 班级排名:%s 全校排名:%s", s.getBanji(), s.getName(), s.getYuwen(), s.getRank2(), s.getRank1())); } log(""); }
시험 배치: 202302
반: 1급, 3급 학생: Zhang Xiaoming 중국어 점수: 130.0 반 순위: 2 전교 순위: 3반: 3학년 1반 학생: Wang Er Xiao 중국어 점수: 128.0 반 순위: 3 전교 순위: 6
반: 3반 학생: Feng Shijie 중국어 점수: 129.0 반 순위: 3 전교 순위: 5반: 3학년 2학년 학생: Ma Gongcheng 중국어 성적: 130.0 반 순위: 2 전체 학교 순위: 3
반: 2학년 3학년 학생: Wei Pianpian 중국어 성적: 136.0 반 순위: 1 학교 순위: 1학교 순위를 보면 공동 1위 2명, 공동 3위 2명이 있고, 공동 2위와 4위가 공석인 것을 볼 수 있습니다
위 내용은 그룹 순위를 얻기 위해 Java에서 순위/오버 함수를 시뮬레이션하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!