连接每行任意长度的列

时间:2015-10-13 11:02:09

标签: sql-server tsql

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

UIAccessibilityTraits

如果不明确指定每个列名,我怎样才能获得相同的结果?

5 个答案:

答案 0 :(得分:1)

您需要使用动态SQL。您可以查询系统catalg视图sys.columns以获取列名,然后使用SQL Server's XML Extension to concatenate the rows to a single string来执行最终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;

ADDENDUM 2

为避免在值为null时添加分隔符,例如而不是以:

结束
1,,,2,3

你只是得到

1,2,3

在生成类似的查询之前,您需要稍微修改一下逻辑:

CONCAT([C1], ',', [C2], ',', [C3])

相反,你想:

CONCAT([C1], ',' + [C2], ',' + [C3])

因为如果',' + [C2]为null,您现在使用[C2],结果将为null,因此将删除分隔符:

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;

ADDENDUM 3

要删除第一列,您可以在ROW_NUMBER()系统目录视图中使用sys.columns,然后排除第一列:

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;

答案 1 :(得分:1)

您需要使用Dynamic-SQL:

警告:

我使用了tempdb($(document).on('click', '.btn_update', function(event){ event.preventDefault(); $.ajax({ url: location.pathname + '/popup', type: "POST", data: { "daily_order_id": 1 } }); }); ),因为我无法在demo中创建普通表。在您的情况下使用您的普通数据库。并将条件更改为:tempdb.sys.columns

LiveDemo

WHERE object_id = OBJECT_ID('table_name')

修改 如果在连接值之间需要特定字符,请使用:

CREATE TABLE #tab(ID INT, C1 INT, C2 INT, C3 INT);

INSERT INTO #tab VALUES (1, 1,2,3), (2, 2,3,4);


DECLARE @cols  NVARCHAR(MAX);

SET @cols = STUFF(     
            (SELECT ',' + QUOTENAME(name)
            FROM tempdb.sys.columns
            WHERE 
              object_id = (SELECT object_id 
                           FROM tempdb.sys.objects 
                           WHERE NAME like '#tab%' AND Type = 'U')
            AND name LIKE 'C%'
            ORDER BY column_id
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');


DECLARE @query NVARCHAR(MAX)=
  N'SELECT ID, CONCAT(<placeholder>) AS concated_columns FROM #tab';

SET @query =  REPLACE(@query, '<placeholder>', @cols);

EXEC [dbo].[sp_executesql]
       @query;

LiveDemo2

答案 2 :(得分:0)

连接任意表中的所有列:

$viewHelperManager = $serviceLocator->get('viewhelpermanager');

// Get new title-part from database
$titlePart = '...' // In this case "The faces behind the team"

// Set HeadTitle
$headtitle = $viewHelperManager->get('headtitle');
$headtitle($node->getNodeName(), 'SET');

答案 3 :(得分:0)

使用动态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

答案 4 :(得分:0)

如果您的表具有主键列,则可以使用相关子查询,如下例所示。 SqlFiddle here

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;