Sql server 每行连接任意长度的列

Sql server 每行连接任意长度的列,sql-server,tsql,Sql Server,Tsql,如何连接每行任意长度的列?我尝试了以下操作,但函数as需要指定列名: SELECT CONCAT([C1], [C2], ...) FROM [dbo.table]; 如何在不明确指定每个列名的情况下获得相同的结果?要在任意表中包含所有列,请执行以下操作: DECLARE @Columns nvarchar(MAX) SELECT @Columns = ISNULL(@Columns + ',','') + COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMN

如何连接每行任意长度的列?我尝试了以下操作,但函数as需要指定列名:

SELECT CONCAT([C1], [C2], ...) FROM [dbo.table];

如何在不明确指定每个列名的情况下获得相同的结果?

要在任意表中包含所有列,请执行以下操作:

DECLARE @Columns nvarchar(MAX)

SELECT @Columns = ISNULL(@Columns + ',','') + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND TABLE_SCHEMA='dbo'

DECLARE @sql nvarchar(MAX)

SET @sql = N'SELECT CONCAT('+@Columns+')
FROM dbo.TableName'

EXEC sp_executesql @sql

您需要使用动态SQL。您可以查询系统目录视图
sys.columns
以获取列名,然后使用给定要执行的最终SQL:

DECLARE @TableName SYSNAME = 'dbo.YourTable';   

DECLARE @SQL NVARCHAR(MAX) = 'SELECT CONCAT(' + 
                            STUFF(( SELECT ',' + QUOTENAME(c.Name)
                                    FROM sys.columns c
                                    WHERE [object_id] = OBJECT_ID(@TableName)
                                    FOR XML PATH(''), TYPE
                                    ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') + ')
                            FROM ' + @TableName + ';';

EXECUTE sp_executesql @SQL;

附录

如果要分隔列,可以在创建列列表时添加进一步的连接:

DECLARE @TableName SYSNAME = 'dbo.YourTable',
        @Delimiter VARCHAR(10) = ', ';

DECLARE @SQL NVARCHAR(MAX) = 'SELECT CONCAT(' + 
                            STUFF(( SELECT ',''' + @Delimiter + ''',' + QUOTENAME(c.Name)
                                    FROM sys.columns c
                                    WHERE [object_id] = OBJECT_ID(@TableName)
                                    FOR XML PATH(''), TYPE
                                    ).value('.', 'NVARCHAR(MAX)'), 1, LEN(@Delimiter) + 5, '') + ')
                            FROM ' + @TableName + ';';

EXECUTE sp_executesql @SQL;
附录2

要避免在值为null时添加分隔符,例如,而不是以以下形式结束:

1,,,2,3
你只需要

1,2,3
在生成如下查询之前,您需要稍微修改逻辑:

CONCAT([C1], ',', [C2], ',', [C3])
相反,您希望:

CONCAT([C1], ',' + [C2], ',' + [C3])
由于您现在使用的是
,“+[C2]
如果
[C2]
为空,则结果将为空,因此将删除分隔符:

DECLARE @TableName SYSNAME = 'dbo.YourTable',
        @Delimiter VARCHAR(10) = ', ';

DECLARE @SQL NVARCHAR(MAX) = 'SELECT CONCAT(' + 
                            STUFF(( SELECT ',''' + @Delimiter + ''' + ' + QUOTENAME(c.Name)
                                    FROM sys.columns c
                                    WHERE [object_id] = OBJECT_ID(@TableName)
                                    FOR XML PATH(''), TYPE
                                    ).value('.', 'NVARCHAR(MAX)'), 1, LEN(@Delimiter) + 7, '') + ')
                            FROM ' + @TableName + ';';
EXECUTE sp_executesql @SQL;

附录3

要删除第一列,可以使用
sys.columns
系统目录视图上的
ROW\u NUMBER()
,然后排除第一列:

DECLARE @TableName SYSNAME = 'dbo.YourTable',
        @Delimiter VARCHAR(10) = ', ';

DECLARE @SQL NVARCHAR(MAX) = 'SELECT CONCAT(' + 
                            STUFF(( SELECT ',''' + @Delimiter + ''' + ' + QUOTENAME(c.Name)
                                    FROM    (   SELECT name, 
                                                        RowNumber = ROW_NUMBER() OVER(ORDER BY column_id)
                                                FROM sys.columns c
                                                WHERE [object_id] = OBJECT_ID(@TableName)
                                            ) AS c
                                    WHERE c.RowNumber != 1 -- not first column
                                    FOR XML PATH(''), TYPE
                                    ).value('.', 'NVARCHAR(MAX)'), 1, LEN(@Delimiter) + 7, '') + ')
                            FROM ' + @TableName + ';';
EXECUTE sp_executesql @SQL;

您需要为此使用动态SQL:

警告:

我使用了tempdb(
tempdb.sys.columns
),因为我无法在演示中创建普通表。在您的情况下,请使用普通数据库。并将条件更改为:
其中object\u id=object\u id('table\u name')


使用动态SQL,记住要考虑空值

declare @sql nvarchar(max), @t sysname, @c sysname  
select @sql = 'select ', @t = '[dbo].[CONTACTS]' /* <---- YOUR TABLE NAME HERE */

declare cols cursor for
    select name from sys.columns where object_id = object_id(@t) order by column_id 
open cols 
fetch next from cols INTO @c

while @@FETCH_STATUS = 0
 begin
    select @sql = @sql + 'convert(nvarchar(max), isnull(' + @c + ', '''')) + '  
    fetch next from cols INTO @c
 end 
close cols 
deallocate cols

select @sql = left(@sql, len(@sql)-2) + ' from ' + @t 
exec sp_executesql @sql
声明@sql nvarchar(max)、@t sysname、@c sysname

选择@sql='select',@t='[dbo].[CONTACTS]'/*如果您的表有一个主键列,您可以使用如下示例所示的相关子查询


没有列名不可能我可以建议一个更好的表名吗?在名称中的表名中包含类似于schema的内容不是很好的实践,在名称中包含表也不是。表名中有句号只是自找麻烦谢谢你,小伙子!这正是我需要的。:)不幸的是,我无法计算我必须更改什么才能使它在我的数据库中工作。@JimBoy将
tempdb.sys.columns
更改为
sys.columns
其中object\u id=object\u id('table\u name')
选项卡更改为
您的\u table\u name
。就这些;)谢谢你的帮助!根据您的解释,我更改了所有内容,但没有显示结果表。@JimBoy
和类似“C%”的名称。
您有类似
C..或
的列吗?
?如果是“更改<代码>”和“C%%”/代码>到“代码>”,名称类似“购买%”/代码> N.B.实际函数<代码> QualAdMe()/代码>比链接括号更安全,请考虑下表->代码>创建表βt(“愚蠢[]名称”VARCHAR(5));
--使用quotename将正确转义为:
[dumby[]]Name]
,而仅仅串联括号将给出
[dumby[]Name]
,从而导致语法错误。虽然我承认这是一个令人憎恶的对象名称,但有时人们需要迎合这一点。谢谢你加雷斯!您的代码在我的SQL Server实例上运行时没有任何错误消息,但我没有得到显示的结果。您知道这是为什么吗?您是否已将
@TableName
的值从
'dbo.YourTable'
更新为实际的表名?非常感谢!)有没有办法在不同的字符串之间放置分隔符?很好!但现在我看到
NULL
也被计算在内。有没有一种简单的方法可以抑制这种情绪?非常感谢您的详细解释!:)最后一个问题:我可以从进程中排除表的第一列吗?
(SELECT ',' + CONCAT(QUOTENAME(name) , ','' ''' )
declare @sql nvarchar(max), @t sysname, @c sysname  
select @sql = 'select ', @t = '[dbo].[CONTACTS]' /* <---- YOUR TABLE NAME HERE */

declare cols cursor for
    select name from sys.columns where object_id = object_id(@t) order by column_id 
open cols 
fetch next from cols INTO @c

while @@FETCH_STATUS = 0
 begin
    select @sql = @sql + 'convert(nvarchar(max), isnull(' + @c + ', '''')) + '  
    fetch next from cols INTO @c
 end 
close cols 
deallocate cols

select @sql = left(@sql, len(@sql)-2) + ' from ' + @t 
exec sp_executesql @sql
SELECT (
        ( SELECT    *
          FROM      dbo.table1 AS t2
          WHERE     t2.C1 = t1.C1 --specify primary key column(s) here
        FOR
          XML PATH('test')
            , TYPE
        )).value('/test[1]', 'nvarchar(MAX)') AS ConcatenatedValue
FROM    dbo.table1 AS t1;