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

グループごとに最初の行を選択する

    SELECT  a, b, c
    FROM    (
            SELECT  *, ROW_NUMBER() OVER (PARTITION BY a ORDER BY b, c) rn
            FROM    mytable
            ) q
    WHERE   rn = 1
    ORDER BY
            a
    

    または

    SELECT  mi.*
    FROM    (
            SELECT  DISTINCT  a
            FROM    mytable
            ) md
    CROSS APPLY
            (
            SELECT  TOP 1 *
            FROM    mytable mi
            WHERE   mi.a = md.a
            ORDER BY
                    b, c
            ) mi
    ORDER BY
            a
    

    (a, b, c)に複合インデックスを作成します クエリがより高速に機能するようにします。

    どちらがより効率的かは、データの分散によって異なります。

    aの明確な値がほとんどない場合 しかし、各a内の多くのレコード 、2番目のクエリの方が適切です。

    インデックス付きのビューを作成することで、さらに改善することができます:

    CREATE VIEW v_mytable_da
    WITH   SCHEMABINDING
    AS
           SELECT  a, COUNT_BIG(*) cnt
           FROM    dbo.mytable
           GROUP BY
                   a
    
    GO
    
    CREATE UNIQUE CLUSTERED INDEX
           pk_vmytableda_a
    ON     v_mytable_da (a)
    
    GO
    
    SELECT  mi.*
    FROM    v_mytable_da md
    CROSS APPLY
            (
            SELECT  TOP 1 *
            FROM    mytable mi
            WHERE   mi.a = md.a
            ORDER BY
                    b, c
            ) mi
    ORDER BY
            a
    


    1. OracleのJSON_QUERY()関数

    2. SQL ServerのVarchar(max)に対してNOT NULLがNULL値を返すのはなぜですか?

    3. SQLServerでテーブル値関数を変更する

    4. 非常に大きなテーブルでの(列ストア)圧縮の楽しみ–パート3