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,
        MIN( Score ) AS MinScore
    FROM Gameshow
    GROUP BY Contestant
    ORDER BY Contestant;

    結果:

    +--------------+------------+
    | Contestant   | MinScore   |
    |--------------+------------|
    | Faye         | 50         |
    | Jet          | 31         |
    | Spike        | 15         |
    +--------------+------------+
    オプション2

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

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

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 2      | 50      |
    | Jet          | 1      | 31      |
    | Spike        | 3      | 15      |
    +--------------+--------+---------+

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

    オプション3

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

    SELECT 
        g1.Contestant, 
        g1.Game,
        g1.Score
    FROM Gameshow g1
    JOIN (
      SELECT Contestant, MIN( 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         | 2      | 50      |
    | Jet          | 1      | 31      |
    | Spike        | 3      | 15      |
    +--------------+--------+---------+

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

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

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

    特定の列の最小値を持つ行をフェッチする別の方法は、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         | 2      | 50      |
    | Jet          | 1      | 31      |
    | Spike        | 3      | 15      |
    +--------------+--------+---------+
    オプション5

    これを行う別の方法は、ウィンドウ関数で一般的なテーブル式を使用することです。

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

    結果:

    +--------------+--------+---------+
    | Contestant   | Game   | Score   |
    |--------------+--------+---------|
    | Faye         | 2      | 50      |
    | Jet          | 1      | 31      |
    | Spike        | 3      | 15      |
    +--------------+--------+---------+

    1. SQLデータベースの代わりに/Redisなどのキー/値ストアを使用する場合

    2. マスターデータベースとしてMongoDBを使用する場合、エンティティ間の関係を実装するために別のグラフデータベースを使用する必要がありますか?

    3. MongoDBのestimatedDocumentCount()

    4. MongoDBコレクションのサブセットを別のコレクションに保存する