如何动态合并行

时间:2019-07-17 09:37:25

标签: sql-server

我有一个包含许多列(偶数列)的表。现在,我需要将第二列和第三列,第四列和第五列,第六列和第七列结合起来……等等。如何实现呢?

我尝试了静态模式,但是动态模式呢?假设有100列或更多列。

create table tb11 ( [id] int,[A] varchar(20),[B] varchar(20),
[C] varchar(20),[D] varchar(20)) 
insert into tb11 values
(1,'a','b','c','d'),
(2,'e','f','g','h'),
(3,'i','j','k','l')

select * from tb11
/*
id   A   B    C   D
---- --- ---- --- ----
 1    a   b    c   d
 2    e   f    g   h
 3    i   j    k   l
*/

select id, 
[A] + [B] as '1' ,
[C] + [D] as '2' 
from tb11

/*output with 3 columns
 id   1     2
 ---- ----- ------
  1    ab    cd
  2    ef    gh
  3    ij    kl
  */

2 个答案:

答案 0 :(得分:0)

您可以使用表的schema来获取列列表并从中创建动态列名称。 同样,通过使用schema仅为新结构创建表script

尝试一下:

    GO

    ;with cte as (
    select ORDINAL_POSITION as slno, COLUMN_NAME from information_schema.columns where table_name = 'tb11'
    )
    select * into #tab_col from cte

    declare @max int 
    set @max = (select Count(*) -1 from #tab_col)

    declare @loop int 
    set @loop = 0

    create table newtab (
    id int  )

    declare @columns nvarchar(max) = ''
    declare @values nvarchar(max) = ''

    while(@Loop <= (@Max/2))
    Begin

    declare @Col1 varchar(100)
    declare @Col2 varchar(100)
    set @Col1 = (select Column_name from #tab_col where slno = @Loop+2)
    set @Col2 = (select Column_name from #tab_col where slno = @Loop+3)
    declare @alter nvarchar(max)
    set @alter = ' Alter table newtab add [' + cast(((@Loop/2)+1) as varchar(100)) + '] nvarchar(max) '
    set @columns = @columns + ',[' + (select cast(((@Loop/2)+1) as varchar(100))) + ']'
    set @values = @values + ',''' +  @Col1 + @Col2 + ''''
    exec sp_executesql @alter
    set @loop = @loop + 2
    End

    set @values =( select  substring( @values, 2, len(@values)))
    select @values
    set @columns =( select  substring( @columns, 2, len(@columns)))
    select @columns


    declare @altertab nvarchar(max)
    set @altertab = ' insert into newtab ( id, ' + @columns + ' ) values ( 1, ' + @values + ' )'


    exec sp_executesql @altertab


    drop table newtab
    Drop table #tab_col

    GO

这不会完全给您答案,但是您会有所了解。

答案 1 :(得分:0)

尝试一下

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = (
    SELECT '
    ' +
    STUFF((
        SELECT ', ' + c.name + ' + ' + c2.name + ' AS [' + c.name + c2.name +']'
        FROM sys.columns c
        INNER JOIN sys.columns c2 ON c2.object_id = c.object_id 
            AND c2.column_id = c.column_id + 1
        WHERE c.[object_id] = o.[object_id]
        AND c.column_id > 1
        AND c.column_id % 2 = 0
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, 'SELECT id, ') + '
    FROM [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + ']' -- select *
    FROM sys.objects o
    WHERE o.[type] = 'U'
        AND o.is_ms_shipped = 0
        AND [name] = 'tb11' 
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')
PRINT @SQL
EXEC sys.sp_executesql @SQL