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

複数の行を 1 つの行に結合する

    そのような動的な列数を持つことはできませんが、データを連結することはできます 文字列に:

    select
        s.ItemID, s.Code, s.Name,
        stuff(
            (
                select ', ' + CAST(sv.SearchValueID AS VARCHAR)
                from ItemSearch as sv
                where sv.ItemID = s.ItemID
                for xml path(''), type
            ).value('.', 'nvarchar(128)')
        , 1, 2, '') as SearchValues
    from Item as s;
    

    または、行をピボットできます PIVOT command または手動で (私は後者のアプローチを好みます。私にとってはより柔軟に思えますが、pivot 特定の状況でコード量を大幅に削減できます ):

    with cte as (
        select
            *,
            row_number() over(partition by sv.ItemID order by sv.SearchValueID) as row_num
        from ItemSearch as sv
    )
    select
        s.ItemID, s.Code, s.Name,
        max(case when sv.row_num = 1 then sv.SearchValueID end) as SearchValueID1,
        max(case when sv.row_num = 2 then sv.SearchValueID end) as SearchValueID2,
        max(case when sv.row_num = 3 then sv.SearchValueID end) as SearchValueID3,
        max(case when sv.row_num = 4 then sv.SearchValueID end) as SearchValueID4
    from Item as s
        inner join cte as sv on sv.ItemID = s.ItemID
    group by s.ItemID, s.Code, s.Name
    

    前のステートメントを動的 SQL に変換することもできます このように:

    declare @stmt nvarchar(max)
    
    select
        @stmt = 
            isnull(@stmt + ',','') + 
            'max(case when sv.row_num = ' + cast(rn as nvarchar(max)) +
            ' then sv.SearchValueID end) as SearchValueID' + cast(rn as nvarchar(max))
    from (
        select distinct row_number() over(partition by ItemID order by SearchValueID) as rn
        from ItemSearch
    ) as a
    
    select @stmt = '
        with cte as (
            select
                *,
                row_number() over(partition by sv.ItemID order by sv.SearchValueID) as row_num
            from ItemSearch as sv
        )
        select
            s.ItemID, s.Code, s.Name,' + @stmt + '
        from Item as s
            inner join cte as sv on sv.ItemID = s.ItemID
        group by s.ItemID, s.Code, s.Name;'
    
    exec dbo.sp_executesql @stmt = @stmt
    

    SQL フィドルのデモ




    1. 2つのSQLクエリ間の減算

    2. 関数の値または数値エラーで、どこが間違っているのか検出できませんOracle

    3. カスケード削除の概念に関するMySql?

    4. MS SQL Server 2008のポートを見つける方法は?