目次
背景
sorted fileld
dataList 並べ替えられたデータ セット
ホームページ Java &#&チュートリアル Javaでランク/オーバー関数をシミュレートしてグループランキングを取得する方法

Javaでランク/オーバー関数をシミュレートしてグループランキングを取得する方法

May 03, 2023 pm 01:52 PM
java rank over

背景

202302クラス 3 年张小明130.00202302三クラス 1毎年##128.00##3年クラス1#謝春華馮世傑马 Gongchengウェイ ピアンピアン 上記のデータがあり、次があると仮定します。各生徒の中国語のシートを数える必要があります。クラス内での科目の得点の順位と、年間全体の順位をどのように達成しますか? rank() over()の実装を考えるのは簡単です。over() は、rank()、dense_rank() と組み合わせて使用​​できる分析関数です。 、および row_number()。
検査バッチ クラス 名前 中文
##王二小 202302
136.00 202302 三级二级
129.00 202302 3 年 2 組
130.00 202302 クラス 2、グレード 3
136.00

構文は次のとおりです:

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("");
}
ログイン後にコピー
結果は次のとおりです。

中国語科目得点ランキングは次のとおりです。

試験バッチ: 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 サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

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

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

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

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

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

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

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

カプセルの量を見つけるためのJavaプログラム カプセルの量を見つけるためのJavaプログラム Feb 07, 2025 am 11:37 AM

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

Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Spring Tool Suiteで最初のSpring Bootアプリケーションを実行するにはどうすればよいですか? Feb 07, 2025 pm 12:11 PM

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

See all articles