Javaでランク/オーバー関数をシミュレートしてグループランキングを取得する方法
背景
検査バッチ | クラス | 名前 | 中文 |
---|---|---|---|
クラス 3 年 | 张小明 | 130.00 | |
三クラス 1毎年 | ##王二小 | ##128.00202302 | ##3年クラス1|
136.00 | 202302 | 三级二级 | |
129.00 | 202302 | 3 年 2 組 | |
130.00 | 202302 | クラス 2、グレード 3 | |
136.00 | 上記のデータがあり、次があると仮定します。各生徒の中国語のシートを数える必要があります。クラス内での科目の得点の順位と、年間全体の順位をどのように達成しますか? | rank() over()の実装を考えるのは簡単です。 |
構文は次のとおりです:
RANK() OVER(PARTITION BY COLUMN ORDER BY COLUMN) dense_rank() OVER(PARTITION BY COLUMN ORDER BY COLUMN) ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
説明: 結果セットをグループ化するために、partition by が使用されます。指定しない場合、結果セット全体がグループとして扱われます。
Rank()関数は主にソートに使用され、シーケンス番号を付与する関数で、ソートされた並列データに同じシーケンス番号が付与され、同順位の順位がクリアされます。
- dense_rank() は、rank() と同じ関数を持ちます。違いは、同順位の順位が空にされないことです。
- row_number( ) 関数は、並列処理に関係なく、順番に使用されます。
- rank 結果は 1,2,2,4 になります。dens_rank 結果は、1,2,2,3 row_number になります。結果は、 1,2 ,3,4 となります。実際のアプリケーションでは、他の外部システムからデータにアクセスする場面が多く、データ量がそれほど多くないため、さらに多くなります。グループのランキングを達成するには Java コードを使用することが重要です。便利です。
詳細な設計と実装ソート定義クラス OrderBy
public 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; } }
このクラスは次の属性を定義します:
sorted fileld
- 昇順かどうか
- ランキングメソッドの取得
このメソッドは次のように定義されています:
<T> void rankOver(List<T> dataList, String[] partitionByFields, List<OrderBy> orderByList, String resultField, int rankType);
ログイン後にコピーこのメソッドは 5 つの入力パラメータを提供します。
dataList 並べ替えられたデータ セット
partitionByFields グループ化フィールドの配列
orderByList 並べ替えフィールド コレクション
resultField ランキング結果が含まれるフィールドstorage
#rankType ランキング方法
1: 同点は考慮されません (row_number の結果は 1、2、3、4)
- 2 : 同点を考慮し、同点が占めているランキングは除外します (順位結果は 1,2,2,4)
- 3: 同点を考慮し、除外しないでください同順位が占めるランキング (dense_rank 1,2,2,3)
- #このメソッドの具体的な実装は次のとおりです #
- ユースケース学生クラスを定義します:
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("");
}
ログイン後にコピー結果は次のとおりです。
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クラス: 3 年 1 組生徒: Zhang Xiaoming 中国語スコア: 130.0 クラスランク: 2 学校ランキング: 3
クラス: Class 1, Grade 3 学生: Wang Er Xiao 中国語スコア: 128.0 クラスランク: 3 学校ランキング: 6クラス: Class 3, 3 年生: Xie Chunhua 中国語スコア: 136.0 クラス ランク: 1 学校ランキング: 1
クラス: Grade 2 3 年生: Feng Shijie 中国語スコア: 129.0 クラス ランク: 3 学校ランキング: 5クラス: 学年3 年生 2 人: Ma Gongcheng 中国語スコア: 130.0 クラス ランク: 2 学校ランキング: 3クラス: Grade 2 クラス 3 生徒: Wei Pianpian 中国語スコア: 136.0 クラス ランク: 1 学校ランキング: 1
学校ランキングには 2 つあることがわかります。1 位に 2 つと 3 位に 2 つが同点で、同点の 2 位と 4
# は空席のままです。
以上がJavaでランク/オーバー関数をシミュレートしてグループランキングを取得する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

カプセルは3次元の幾何学的図形で、両端にシリンダーと半球で構成されています。カプセルの体積は、シリンダーの体積と両端に半球の体積を追加することで計算できます。このチュートリアルでは、さまざまな方法を使用して、Javaの特定のカプセルの体積を計算する方法について説明します。 カプセルボリュームフォーミュラ カプセルボリュームの式は次のとおりです。 カプセル体積=円筒形の体積2つの半球体積 で、 R:半球の半径。 H:シリンダーの高さ(半球を除く)。 例1 入力 RADIUS = 5ユニット 高さ= 10単位 出力 ボリューム= 1570.8立方ユニット 説明する 式を使用してボリュームを計算します。 ボリューム=π×R2×H(4

Spring Bootは、Java開発に革命をもたらす堅牢でスケーラブルな、生産対応のJavaアプリケーションの作成を簡素化します。 スプリングエコシステムに固有の「構成に関する慣習」アプローチは、手動のセットアップを最小化します。
