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

文字列を連結/集約するための最適な方法

    解決策

    最適の定義 変更することもできますが、通常のTransactSQLを使用してさまざまな行の文字列を連結する方法を次に示します。これはAzureで正常に機能するはずです。

    ;WITH Partitioned AS
    (
        SELECT 
            ID,
            Name,
            ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Name) AS NameNumber,
            COUNT(*) OVER (PARTITION BY ID) AS NameCount
        FROM dbo.SourceTable
    ),
    Concatenated AS
    (
        SELECT 
            ID, 
            CAST(Name AS nvarchar) AS FullName, 
            Name, 
            NameNumber, 
            NameCount 
        FROM Partitioned 
        WHERE NameNumber = 1
    
        UNION ALL
    
        SELECT 
            P.ID, 
            CAST(C.FullName + ', ' + P.Name AS nvarchar), 
            P.Name, 
            P.NameNumber, 
            P.NameCount
        FROM Partitioned AS P
            INNER JOIN Concatenated AS C 
                    ON P.ID = C.ID 
                    AND P.NameNumber = C.NameNumber + 1
    )
    SELECT 
        ID,
        FullName
    FROM Concatenated
    WHERE NameNumber = NameCount
    

    説明

    アプローチは3つのステップに要約されます:

    1. OVERを使用して行に番号を付けます およびPARTITION 連結の必要に応じて、それらをグループ化して順序付けします。結果はPartitioned CTE。後で結果をフィルタリングするために、各パーティションの行数を保持します。

    2. 再帰CTEの使用(Concatenated )行番号を繰り返し処理します(NameNumber 列)Nameを追加します FullNameの値 列。

    3. NameNumberが最も高い結果を除くすべての結果を除外します 。

    このクエリを予測可能にするには、両方のグループ化を定義する必要があることに注意してください(たとえば、同じIDのシナリオ行で 連結されます)および並べ替え(連結の前に文字列をアルファベット順に並べ替えると仮定しました)。

    次のデータを使用して、SQLServer2012でソリューションをすばやくテストしました。

    INSERT dbo.SourceTable (ID, Name)
    VALUES 
    (1, 'Matt'),
    (1, 'Rocks'),
    (2, 'Stylus'),
    (3, 'Foo'),
    (3, 'Bar'),
    (3, 'Baz')
    

    クエリ結果:

    ID          FullName
    ----------- ------------------------------
    2           Stylus
    3           Bar, Baz, Foo
    1           Matt, Rocks
    


    1. PostGISのバッファ(円)

    2. 複合主キーを外部キーとして使用する

    3. AccessでUNPIVOTをシミュレートする方法は?

    4. Java SQLエラー:リレーションTable_Nameが存在しません