sql >> データベース >  >> NoSQL >> MongoDB

SQLでグループの最大値を持つ行を選択する5つの方法

    SQLを使用して、グループ内で最大値を持つ行のみを返すための5つのオプションを次に示します。

    これらの例は、MySQL、MariaDB、Oracle、PostgreSQL、SQLite、SQLServerなどのほとんどの主要なRDBMSで機能します。

    サンプルデータ

    次のデータを含むテーブルがあるとします。

    SELECT * FROM Gameshow;

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 1      | 85      |
    | Faye         | 2      | 50      |
    | Faye         | 3      | 63      |
    | Jet          | 1      | 31      |
    | Jet          | 2      | 40      |
    | Jet          | 3      | 51      |
    | Spike        | 1      | 25      |
    | Spike        | 2      | 27      |
    | Spike        | 3      | 15      |
    +--------------+--------+---------+

    そして、各出場者の最高スコアを取得したいとします。

    オプション1

    すばやく簡単なオプションは、SQL GROUP BYを使用してクエリを作成することです。 条項:

    SELECT 
        Contestant,
        MAX( Score ) AS MaxScore
    FROM Gameshow
    GROUP BY Contestant
    ORDER BY Contestant;

    結果:

    +--------------+------------+
    | Contestant   | MaxScore   |
    |--------------+------------|
    | Faye         | 85         |
    | Jet          | 51         |
    | Spike        | 27         |
    +--------------+------------+
    オプション2

    各競技者が最大スコアを取得するためにプレイしたゲームを含める場合、そのための1つの方法は、次のような相関サブクエリを使用することです。

    SELECT 
        Contestant,
        Game,
        Score
    FROM Gameshow g1
    WHERE Score = ( SELECT MAX( g2.Score )
                  FROM Gameshow g2
                  WHERE g1.Contestant = g2.Contestant )
    ORDER BY Contestant;

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 1      | 85      |
    | Jet          | 3      | 51      |
    | Spike        | 2      | 27      |
    +--------------+--------+---------+

    相関サブクエリは、サブクエリの外部からの1つ以上の列を参照します。相関サブクエリは、主に、外部クエリによって選択される可能性のある行ごとに1回ずつサブクエリが繰り返し実行されるため、非効率になる可能性があります。相関サブクエリは、繰り返しサブクエリとも呼ばれます。

    オプション3

    あるいは、次のような無相関のサブクエリを使用することもできます:

    SELECT 
        g1.Contestant, 
        g1.Game,
        g1.Score
    FROM Gameshow g1
    JOIN (
      SELECT Contestant, MAX( Score ) AS Score
      FROM Gameshow
      GROUP BY Contestant ) AS g2
      ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
    ORDER BY Contestant ASC;

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 1      | 85      |
    | Jet          | 3      | 51      |
    | Spike        | 2      | 27      |
    +--------------+--------+---------+

    相関のないサブクエリは、実行のために外部クエリに依存しません。外部クエリとは完全に独立して実行できます。

    Oracleでは、ASを削除する必要があります 列エイリアスを宣言する場合:

    SELECT 
        g1.Contestant, 
        g1.Game,
        g1.Score
    FROM Gameshow g1
    JOIN (
      SELECT Contestant, MAX( Score ) Score
      FROM Gameshow
      GROUP BY Contestant ) g2
      ON g1.Contestant = g2.Contestant AND g1.Score = g2.Score
    ORDER BY Contestant ASC;
    オプション4

    もう1つのオプションは、LEFT JOINを使用することです。 、このように:

    SELECT 
        g1.Contestant, 
        g1.Game,
        g1.Score
    FROM Gameshow g1
    LEFT JOIN Gameshow g2 ON 
        g1.Contestant = g2.Contestant AND g1.Score < g2.Score
    WHERE g2.Contestant IS NULL
    ORDER BY g1.Contestant ASC;

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 1      | 85      |
    | Jet          | 3      | 51      |
    | Spike        | 2      | 27      |
    +--------------+--------+---------+
    オプション5

    特定の列で最大値を持つ行をフェッチする別の方法は、ウィンドウ関数で一般的なテーブル式を使用することです。

    WITH cte AS (
       SELECT Contestant, Game, Score,
                RANK() OVER ( PARTITION BY Contestant
                ORDER BY Score DESC
                ) AS r
        FROM Gameshow
    )
    SELECT Contestant, Game, Score
    FROM cte
    WHERE r = 1
    ORDER BY Contestant ASC;

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 1      | 85      |
    | Jet          | 3      | 51      |
    | Spike        | 2      | 27      |
    +--------------+--------+---------+

    1. Mongoidを使用する代わりにRubyから直接MongoDBをクエリする方法は?

    2. MongoDBドキュメントの二重にネストされた配列から要素を削除する方法。

    3. アップサートによるマングース重複キーエラー

    4. MongoDB内部リストに要素を挿入するにはどうすればよいですか?