ホームページ >データベース >mysql チュートリアル >リレーショナル データベースでグループごとの最大値を持つ行を効率的に取得するにはどうすればよいですか?

リレーショナル データベースでグループごとの最大値を持つ行を効率的に取得するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2025-01-21 08:03:10901ブラウズ

How Can I Efficiently Retrieve Rows with the Maximum Value per Group in a Relational Database?

リレーショナル データベースのグループ内の最大値を効率的に見つける

リレーショナル データベース内でグループの整合性を維持しながら、特定の列の最大値を含む行を抽出するのは複雑な場合があります。この記事では、クエリ効率を優先して、一意の ID ごとに最大のラウンド番号を持つ行を取得するという課題に取り組みます。

1 つのメソッドはサブクエリを使用します。

<code class="language-sql">SELECT * FROM
(SELECT id, round,
CASE WHEN (MAX(round) OVER (PARTITION BY id)) = round THEN score ELSE NULL END score
 FROM
 SCORES
 where id in (1,2,3)
) scorevals
WHERE
scorevals.round is not null;</code>

ただし、このアプローチは、後処理のフィルタリング手順により非効率的です。

パフォーマンスを向上させるには、ウィンドウ関数の使用を検討してください。

<code class="language-sql">SELECT DISTINCT
       id
      ,max(round) OVER (PARTITION BY id) AS round
      ,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score
FROM   SCORES
WHERE  id IN (1,2,3)
ORDER  BY id;</code>

このクエリは、ウィンドウ関数を使用して各 ID の最大ラウンドを決定し、対応するスコアを取得します。 DISTINCT キーワードにより、ID ごとに 1 行が確保されます。

同じウィンドウ関数を 2 回使用する、より高速になる可能性のある代替案:

<code class="language-sql">SELECT DISTINCT
       id
      ,first_value(round) OVER (PARTITION BY id ORDER BY round DESC) AS round
      ,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score
FROM   SCORES
WHERE  id IN (1,2,3)
ORDER  BY id;</code>

どちらの最適化されたソリューションも不必要なフィルタリングを回避し、サブクエリのアプローチと比較してクエリの実行時間が短縮されます。

以上がリレーショナル データベースでグループごとの最大値を持つ行を効率的に取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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