sql >> データベース >  >> RDS >> Database

各GROUPBYグループの最初の行を選択する方法

    問題:

    GROUP BYを使用してデータをグループ化しました 各グループの最初の行のみを表示したい。

    例:

    データベースには、exam_results 次の表のデータを使用:

    first_name last_name 年 結果
    ジョン クライン 2020 40
    エディス 黒 2020 43
    マーク ジョンソン 2019 32
    ローラ 夏 2020 35
    ケイト スミス 2019 41
    ジェイコブ 黒 2019 44
    トム ベネット 2020 38
    エミリー ケリー 2020 43

    毎年、最高のresultを持つ生徒を見つけましょう 。グループで最高の成績を収めている生徒が2人いる場合は、そのうちの1人を任意に選択して表示します。

    解決策:

    WITH added_row_number AS (
      SELECT
        *,
        ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number
      FROM exam_results
    )
    SELECT
      *
    FROM added_row_number
    WHERE row_number = 1;
    

    結果は次のとおりです。

    first_name last_name 年 結果 row_number
    Jacob 黒 2019 44 1
    エミリー ケリー 2020 43 1

    ディスカッション:

    まず、各グループ内の各行に番号を割り当てるCTEを作成する必要があります。これを行うには、ROW_NUMBER()を使用できます 働き。 OVER()で 、行を分割するグループを指定します(PARTITION BY )および行に番号を割り当てる順序(ORDER BY 。

    内部クエリの結果を見てください:

    SELECT
      *,
      ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number
    FROM exam_results;
    
    first_name last_name 年 結果 row_number
    Jacob 黒 2019 44 1
    ケイト スミス 2019 41 2
    マーク ジョンソン 2019 32 3
    エミリー ケリー 2020 43 1
    エディス 黒 2020 43 2
    ジョン クライン 2020 40 3
    トム ベネット 2020 38 4
    ローラ 夏 2020 35 5

    各グループ内の行番号(つまり、年)を割り当てます。各行には、resultの値に基づいた行番号があります 桁。 DESCのため、行は降順で並べ替えられます ORDER BY resultの後のキーワード 。 resultの値が同じグループ内に複数の行がある場合でも 、行にはまだ異なる番号が付けられています。ここで、EdithBlackとEmilyKellyのresultは同じです。 ただし、行番号は異なります。この動作を変更し、グループ内の同じ結果に同じ行番号を割り当てるには、RANK()を使用します またはDENSE_RANK() ROW_NUMBER()の代わりに 。

    外部クエリでは、CTE(added_row_number )そしてWHEREを使用します 各グループから表示する行を指定する条件。ここでは、最初の行を表示するため、条件はrow_number = 1です。 。

    たとえば、2番目の行を取得するようにソリューションを簡単に変更できることに注意してください。 各グループの。

    WITH added_row_number AS (
      SELECT
        *,
        ROW_NUMBER() OVER(PARTITION BY year ORDER BY result DESC) AS row_number
      FROM exam_results
    )
    SELECT
      *
    FROM added_row_number
    WHERE row_number = 2;
    

    結果は次のとおりです。

    first_name last_name 年 結果 row_number
    ケイト スミス 2019 41 2
    エディス 黒 2020 43 2

    一方、2番目に高い値の行を取得する場合 resultの 各グループ内で、DENSE_RANK()を使用する必要があります 働き。 ROW_NUMBER() 関数は、グループ内の各行に連続した番号を作成します。その結果、同じ結果であるDENSE_RANK()の行に異なる値が割り当てられます。 関数は、同じ結果の行に同じ番号を与えます。

    WITH added_dense_rank AS (
      SELECT
        *,
        DENSE_RANK() OVER(PARTITION BY year ORDER BY result DESC) AS rank
      FROM exam_results
    )
    SELECT
      *
    FROM added_dense_rank
    WHERE rank = 2;
    
    first_name last_name 年 結果 ランク
    ケイト スミス 2019 41 2
    ジョン クライン 2020 40 2

    JohnKleinのresult (40)の値が2番目に高いことがわかります。 John Kleinは実際にはグループの3人目ですが、最初の2人の生徒は同じresultを持っています どちらもrank = 1です 。


    1. SQLiteデータベースのクローンを作成する

    2. SQLServerで月の最初の日を取得する3つの方法

    3. SQL ServerのPARSE()とCAST()とCONVERT()の違い:違いは何ですか?

    4. 言語設定がSQLServerのFORMAT()結果にどのように影響するか(T-SQLの例)