目次
1. ROW _NUMBER" > 1. ROW _NUMBER
二、RANK" >二、RANK
三、DENSE_RANK" >三、DENSE_RANK
四、NTILE" >四、NTILE
ホームページ データベース mysql チュートリアル 4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

Jun 14, 2018 pm 04:48 PM
sql

ランキング機能はSql Server2005の新機能です。それぞれの使い方と違いを簡単に紹介します。新しい Order テーブルを作成し、効果を確認できるようにいくつかの初期データを追加します。

テーブル構造と初期データSql

テーブル構造と初期データ図を添付します:

4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

1. ROW _NUMBER

目的of row_number これは、ソートに使用するのが最適です。通常、クエリされたレコードの各行にシリアル番号を生成し、重複することなく順番にソートします。 row_number 関数を使用する場合は、並べ替えてシリアル番号を生成する列を選択する必要があることを確認します。 Row_number の使用例:


select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order]
ログイン後にコピー


クエリ結果は以下のようになります:

4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

列はによって生成されたシリアル番号列row_number 関数。基本的には、まず over 句の並べ替えステートメントを使用してレコードを並べ替え、次にこの順序でシリアル番号を生成します。 over 句の order by 句は、SQL ステートメントの order by 句とはまったく関係がありません。たとえば、次の SQL では、over 句は次のように配置されます。 SQL ステートメント内で SubTime に従って降順に並べ替えます。 次に、TotalPrice で降順に並べ替えます。


select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order] order by [TotalPrice] desc
ログイン後にコピー


  查询结果如下图所示:

  over子句和sql语句中的order by 可完全不同-晓菜鸟

  利用row_number可以实现web程序的分页,我们来查询指定范围的表数据。例:根据订单提交时间倒序排列获取第三至第五条数据。


with orderSection as(    select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [SubTime] desc
ログイン後にコピー


  查询结果如下图所示:

  4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

  注意:在使用row_number实现分页时需要特别注意一点,over子句中的order by 要与Sql排序记录中的order by 保持一致,否则得到的序号可能不是连续的。下面我们写一个例子来证实这一点,将上面Sql语句中的排序字段由SubTime改为TotalPrice。另外提一下,对于带有子查询和CTE的查询,子查询和CTE查询有序并不代表整个查询有序,除非显示指定了order by。


with orderSection as(    select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [TotalPrice] desc
ログイン後にコピー


  查询结果如下图所示:

  over子句中的order by 与sql排序的order by 不一致-晓菜鸟

  

二、RANK

  rank函数用于返回结果集的分区内每行的排名, 行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。可能我描述的比较苍白,理解起来也比较吃力,我们直接上代码,rank函数的使用方法与row_number函数完全相同。


select RANK() OVER(order by [UserId]) as rank,* from [Order]
ログイン後にコピー


  查询结果如下图所示:

  4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

  由上图可以看出,rank函数在进行排名时,同一组的序号是一样的,而后面的则是根据当前的记录数依次类推,图中第一、二条记录的用户Id相同,所以他们的序号是一样的,第三条记录的序号则是3。  

 

三、DENSE_RANK

  dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,rank值紧接上一次的rank值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第四名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。将上面的Sql语句改由dense_rank函数来实现。


select DENSE_RANK() OVER(order by [UserId]) as den_rank,* from [Order]
ログイン後にコピー


  查询结果如下图所示:

  4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

  图中第一、二条记录的用户Id相同,所以他们的序号是一样的,第三条记录的序号紧接上一个的序号,所以为2不为3,后面的依此类推。

四、NTILE

  ntile函数可以对序号进行分组处理,将有序分区中的行分发到指定数目的组中。 各个组有编号,编号从一开始。 对于每一个行,ntile 将返回此行所属的组的编号。这就相当于将查询出来的记录集放到指定长度的数组中,每一个数组元素存放一定数量的记录。ntile函数为每条记录生成的序号就是这条记录所有的数组元素的索引(从1开始)。也可以将每一个分配记录的数组元素称为“桶”。ntile函数有一个参数,用来指定桶数。下面的SQL语句使用ntile函数对Order表进行了装桶处理:


select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]
ログイン後にコピー


  查询结果如下图所示:

  4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

  Order表的总记录数是6条,而上面的Sql语句ntile函数指定的组数是4,那么Sql Server2005是怎么来决定每一组应该分多少条记录呢?这里我们就需要了解ntile函数的分组依据(约定)。

  ntile函数的分组依据(约定):

  1、每组的记录数不能大于它上一组的记录数,即编号小的桶放的记录数不能小于编号大的桶。也就是说,第1组中的记录数只能大于等于第2组及以后各组中的记录数。

  2、所有组中的记录数要么都相同,要么从某一个记录较少的组(命名为X)开始后面所有组的记录数都与该组(X组)的记录数相同。也就是说,如果有个组,前三组的记录数都是9,而第四组的记录数是8,那么第五组和第六组的记录数也必须是8。

  这里对约定2进行详细说明一下,以便于更好的理解。

  首先系统会去检查能不能对所有满足条件的记录进行平均分组,若能则直接平均分配就完成分组了;若不能,则会先分出一个组,这个组分多少条记录呢?就是 (总记录数/总组数)+1 条,之所以分配 (总记录数/总组数)+1 条是因为当不能进行平均分组时,总记录数%总组数肯定是有余的,又因为分组约定1,所以先分出去的组需要+1条。

  分完之后系统会继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若不能,则再分出去一组,这个组的记录数也是(总记录数/总组数)+1条。

  然后系统继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若还是不能,则再分配出去一组,继续比较余下的......这样一直进行下去,直至分组完成。

  举个例子,将51条记录分配成5组,51%5==1不能平均分配,则先分出去一组(51/5)+1=11条记录,然后比较余下的 51-11=40 条记录能否平均分配给未分配的4组,能平均分配,则剩下的4组,每组各40/4=10 条记录,分配完成,分配结果为:11,10,10,10,10,晓菜鸟我开始就错误的以为他会分配成 11,11,11,11,7。

  根据上面的两个约定,可以得出如下的算法:

 


4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

//mod表示取余,p表示取整.if(记录总数 mod 桶数==0)
{
  recordCount=记录总数 p 桶数;
  //将每桶的记录数都设为recordCount.}else{
  recordCount1=记录总数 p 桶数+1;
  int n=1;//n表示桶中记录数为recordCount1的最大桶数.  m=recordCount1*n;  while(((记录总数-m) mod (桶数- n)) !=0)
  {
    n++;
    m=recordCount1*n;
  }
  recordCount2=(记录总数-m) p (桶数-n);
  //将前n个桶的记录数设为recordCount1.  //将n+1个至后面所有桶的记录数设为recordCount2.}
ログイン後にコピー

4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

 

 NTILE()函数算法实现代码

  

  根据上面的算法,如果总记录数为59,总组数为5,则 n=4 , recordCount1=12 , recordCount2=11,分组结果为 :12,12,12,12,11。

  如果总记录数为53,总组数为5,则 n=3 , recordCount1=11 , recordCount2=10,分组结果为:11,11,11,10,10。

  就拿上面的例子来说,总记录数为6,总组数为4,通过算法得到 n=2 , recordCount1=2 , recordCount2=1,分组结果为:2,2,1,1。

 


select ntile,COUNT([ID]) recordCount from (    select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]) as tgroup by t.ntile
ログイン後にコピー


 

  运行Sql,分组结果如图:

  4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介

  比对算法与Sql Server的分组结果是一致的,说明算法没错。:)

 

总结:

在使用排名函数的时候需要注意以下三点:

1.ランキング関数にはOVER句が必要です。

2. ランキング関数には、ORDER BYを含むOVER句が必要です。

3.グループ内で1から並べ替えます。

この記事では、SQL の 4 つの主要なランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) に関連する知識について説明します。その他の関連コンテンツについては、php 中国語 Web サイトを参照してください。

関連する推奨事項:

Mysql の一般的なベンチマーク ツール

Mysql 関数関連の説明

SQLLite 関連のコンテンツ

以上が4 つの主要な SQL ランキング関数 (ROW_NUMBER、RANK、DENSE_RANK、NTILE) の紹介の詳細内容です。詳細については、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)

Hibernate フレームワークにおける HQL と SQL の違いは何ですか? Hibernate フレームワークにおける HQL と SQL の違いは何ですか? Apr 17, 2024 pm 02:57 PM

HQL と SQL は Hibernate フレームワークで比較されます。HQL (1. オブジェクト指向構文、2. データベースに依存しないクエリ、3. タイプ セーフティ)、SQL はデータベースを直接操作します (1. データベースに依存しない標準、2. 複雑な実行可能ファイル)。クエリとデータ操作)。

Oracle SQLでの除算演算の使用法 Oracle SQLでの除算演算の使用法 Mar 10, 2024 pm 03:06 PM

「OracleSQLでの除算演算の使用方法」 OracleSQLでは、除算演算は一般的な数学演算の1つです。データのクエリと処理中に、除算演算はフィールド間の比率を計算したり、特定の値間の論理関係を導出したりするのに役立ちます。この記事では、OracleSQL での除算演算の使用法を紹介し、具体的なコード例を示します。 1. OracleSQL における除算演算の 2 つの方法 OracleSQL では、除算演算を 2 つの異なる方法で実行できます。

Oracle と DB2 の SQL 構文の比較と相違点 Oracle と DB2 の SQL 構文の比較と相違点 Mar 11, 2024 pm 12:09 PM

Oracle と DB2 は一般的に使用される 2 つのリレーショナル データベース管理システムであり、それぞれに独自の SQL 構文と特性があります。この記事では、Oracle と DB2 の SQL 構文を比較し、相違点を示し、具体的なコード例を示します。データベース接続 Oracle では、次のステートメントを使用してデータベースに接続します: CONNECTusername/password@database DB2 では、データベースに接続するステートメントは次のとおりです: CONNECTTOdataba

MyBatis動的SQLタグのSetタグ機能の詳細説明 MyBatis動的SQLタグのSetタグ機能の詳細説明 Feb 26, 2024 pm 07:48 PM

MyBatis 動的 SQL タグの解釈: Set タグの使用法の詳細な説明 MyBatis は、豊富な動的 SQL タグを提供し、データベース操作ステートメントを柔軟に構築できる優れた永続層フレームワークです。このうち、Set タグは、UPDATE ステートメントで SET 句を生成するために使用され、更新操作でよく使用されます。この記事では、MyBatis での Set タグの使用法を詳細に説明し、特定のコード例を通じてその機能を示します。 SetタグとはMyBatiで使用するSetタグです。

SQL の ID 属性は何を意味しますか? SQL の ID 属性は何を意味しますか? Feb 19, 2024 am 11:24 AM

SQL における Identity とは何ですか? 具体的なコード例が必要です。SQL では、Identity は自動インクリメント数値の生成に使用される特別なデータ型です。多くの場合、テーブル内のデータの各行を一意に識別するために使用されます。 Identity 列は、各レコードが一意の識別子を持つようにするために、主キー列と組み合わせてよく使用されます。この記事では、Identity の使用方法といくつかの実用的なコード例について詳しく説明します。 Identity の基本的な使用方法は、テーブルを作成するときに Identity を使用することです。

Java は MySQL ドライバー インターセプターをどのように使用して、時間のかかる SQL 計算を実装しますか? Java は MySQL ドライバー インターセプターをどのように使用して、時間のかかる SQL 計算を実装しますか? May 27, 2023 pm 01:10 PM

背景: 企業のニーズの 1 つは、企業の既存のリンク トラッキング ログ コンポーネントが MySQL の SQL 実行時間の出力をサポートする必要があるということです。リンク トラッキングを実装する一般的な方法は、サードパーティのフレームワークまたはツールによって提供されるインターセプタ インターフェイスまたはフィルタ インターフェイスを実装することです。 MySQL も例外ではなく、実際には、MySQL によって駆動されるインターセプタ インターフェイスを実装しているだけです。 MySQL チャネルにはさまざまなバージョンがあり、バージョンごとにインターセプタ インターフェイスが異なるため、使用する MySQL ドライバのバージョンに応じて応答インターセプタを実装する必要があります。次に、MySQL チャネル 5 と 6 をそれぞれ紹介します8。バージョンの実装。ここでは、Statem を実装する例として MySQL チャネル 5.1.18 バージョンを使用して MySQL5 を実装します。

SQL の 5120 エラーを解決する方法 SQL の 5120 エラーを解決する方法 Mar 06, 2024 pm 04:33 PM

解決策: 1. ログインしているユーザーがデータベースにアクセスまたは操作するための十分な権限を持っているかどうかを確認し、ユーザーが正しい権限を持っているかどうかを確認します; 2. SQL Server サービスのアカウントに指定されたファイルまたはデータベースにアクセスする権限があるかどうかを確認します。 3. 指定されたデータベース ファイルが他のプロセスによって開かれているかロックされているかどうかを確認し、ファイルを閉じるか解放して、クエリを再実行します。管理者として試してください。Management Studio をなどとして実行します。

SQL ステートメントを使用せずに Springboot+Mybatis-plus を実装して複数のテーブルを追加する方法 SQL ステートメントを使用せずに Springboot+Mybatis-plus を実装して複数のテーブルを追加する方法 Jun 02, 2023 am 11:07 AM

Springboot+Mybatis-plus が SQL ステートメントを使用して複数テーブルの追加操作を実行しない場合、私が遭遇した問題は、テスト環境で思考をシミュレートすることによって分解されます: パラメーターを含む BrandDTO オブジェクトを作成し、パラメーターをバックグラウンドに渡すことをシミュレートします。 Mybatis-plus で複数テーブルの操作を実行するのは非常に難しいことを理解してください。Mybatis-plus-join などのツールを使用しない場合は、対応する Mapper.xml ファイルを設定し、臭くて長い ResultMap を設定するだけです。対応する SQL ステートメントを記述します。この方法は面倒に見えますが、柔軟性が高く、次のことが可能です。

See all articles