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の例)