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

SQLは、列の最大値を持つ行のみを選択します

    一見...

    必要なのはGROUP BYだけです MAXを含む句 集計関数:

    SELECT id, MAX(rev)
    FROM YourTable
    GROUP BY id
    

    そんなに簡単なことはありませんよね?

    contentが必要だと気づきました 列も同様です。

    これはSQLで非常によくある質問です。あるグループ識別子ごとに、列に最大値を持つ行のデータ全体を見つけます。私のキャリアの中でそれをたくさん聞いた。実際、それは私が現在の仕事の技術面接で答えた質問の1つでした。

    実際、Stack Overflowコミュニティが次のような質問に対処するためだけに単一のタグを作成することは非常に一般的です:

    基本的に、その問題を解決するには2つのアプローチがあります。

    単純なgroup-identifier, max-value-in-groupとの結合 サブクエリ

    このアプローチでは、最初にgroup-identifier, max-value-in-groupを見つけます。 (上記ですでに解決済み)サブクエリで。次に、両方のgroup-identifierで同等にテーブルをサブクエリに結合します およびmax-value-in-group

    SELECT a.id, a.rev, a.contents
    FROM YourTable a
    INNER JOIN (
        SELECT id, MAX(rev) rev
        FROM YourTable
        GROUP BY id
    ) b ON a.id = b.id AND a.rev = b.rev
    

    自己による左結合、結合条件とフィルターの調整

    このアプローチでは、テーブルをそれ自体と結合したままにします。同等性はgroup-identifierに含まれます 。次に、2つのスマートな動き:

    1. 2番目の結合条件は、左側の値が右側の値よりも小さいことです
    2. 手順1を実行すると、実際に最大値を持つ行はNULLになります。 右側(LEFT JOIN 、 覚えて?)。次に、結合された結果をフィルタリングして、右側がNULLである行のみを表示します。 。

    したがって、最終的には次のようになります:

    SELECT a.*
    FROM YourTable a
    LEFT OUTER JOIN YourTable b
        ON a.id = b.id AND a.rev < b.rev
    WHERE b.id IS NULL;
    

    結論

    どちらのアプローチでもまったく同じ結果が得られます。

    max-value-in-groupの行が2つある場合 group-identifierの場合 、両方の行が両方のアプローチの結果になります。

    どちらのアプローチもSQLANSIと互換性があるため、「フレーバー」に関係なく、お気に入りのRDBMSで機能します。

    どちらのアプローチもパフォーマンスに優れていますが、マイレージは異なる場合があります(RDBMS、DB構造、インデックスなど)。したがって、一方のアプローチをもう一方のアプローチよりも選択する場合は、ベンチマーク 。そして、あなたにとって最も意味のあるものを選ぶようにしてください。



    1. Python:サウンドによるデータのクエリ

    2. MySQL / MariaDB/Perconaサーバーのアップグレードプロセスの自動テスト

    3. PG ::DuplicateTable:エラー:リレーション投稿はすでに存在します

    4. カスタムSERIAL/値のグループごとの自動インクリメント