如何将一行中的所有值连接成字符串?

时间:2018-10-16 08:13:59

标签: sql sql-server tsql

假设我有一行数据,存储如下:

    ------------------------
   | Col 1 | Col 2 | Col 3  |
   |------------------------|
   |  Foo  |  Bar  | Foobar |

我该如何将其隐藏为单个字符串,如下所示?

Foo-Bar-Foobar

此表中的列标题(和列标题数)未知,因此按列名进行选择不是一个选项(?)。

请注意,我并不是要在列中合并值列表,而是在一行中合并值存储。我还希望避免使用数据透视,因为我将处理大量数据,并且不想影响性能。

4 个答案:

答案 0 :(得分:2)

在这种情况下,我真的很喜欢XML处理通用集的强大功能:

SELECT STUFF(b.query('
                        for $element in ./*
                        return
                        <x>;{$element/text()}</x>
                       ').value('.','nvarchar(max)'),1,1,'')
FROM 
(   
    SELECT TOP 3 * FROM sys.objects o FOR XML PATH('row'),ELEMENTS XSINIL,TYPE
) A(a)
CROSS APPLY a.nodes('/row') B(b);

结果

sysrscols;3;4;0;S ;SYSTEM_TABLE;2017-08-22T19:38:02.860;2017-08-22T19:38:02.867;1;0;0
sysrowsets;5;4;0;S ;SYSTEM_TABLE;2009-04-13T12:59:05.513;2017-08-22T19:38:03.197;1;0;0
sysclones;6;4;0;S ;SYSTEM_TABLE;2017-08-22T19:38:03.113;2017-08-22T19:38:03.120;1;0;0

备注

有些事情要提

  • 我将;用作分隔符,因为-可能会因包含连字符的值(例如DATE)而中断
  • 我使用TOP 3中的sys.objects来创建一个易俗气的样本
  • 感谢Zohard Peled,我添加了ELEMENTS XSINIL,以强制引擎不要忽略NULL值。

UPDATE在2016之前的版本中创建JSON

您可以尝试在2016年之前的版本中创建JSON字符串

SELECT '{' 
      + STUFF(b.query('
                        for $element in ./*
                        return
                        <x>,"{local-name($element)}":"{$element/text()}"</x>
                       ').value('.','nvarchar(max)'),1,1,'')
      + '}'
FROM 
(   
    SELECT TOP 3 * FROM sys.objects o FOR XML PATH('row'),TYPE
) A(a)
CROSS APPLY a.nodes('/row') B(b);

结果

{"name":"sysrscols","object_id":"3","schema_id":"4","parent_object_id":"0","type":"S ","type_desc":"SYSTEM_TABLE","create_date":"2017-08-22T19:38:02.860","modify_date":"2017-08-22T19:38:02.867","is_ms_shipped":"1","is_published":"0","is_schema_published":"0"}
{"name":"sysrowsets","object_id":"5","schema_id":"4","parent_object_id":"0","type":"S ","type_desc":"SYSTEM_TABLE","create_date":"2009-04-13T12:59:05.513","modify_date":"2017-08-22T19:38:03.197","is_ms_shipped":"1","is_published":"0","is_schema_published":"0"}
{"name":"sysclones","object_id":"6","schema_id":"4","parent_object_id":"0","type":"S ","type_desc":"SYSTEM_TABLE","create_date":"2017-08-22T19:38:03.113","modify_date":"2017-08-22T19:38:03.120","is_ms_shipped":"1","is_published":"0","is_schema_published":"0"}

提示

您也可以在此查询中添加ELEMENTS XSINIL。这取决于您是否想简单地忽略NULL,还是要将它们包含为"SomeColumn":""

答案 1 :(得分:1)

只需执行SELECT CONCAT(col1,col2,col3) FROM table

但是,如果您想使其整洁

使用: SELECT CONCAT(col1,'-',col2,'-',col3) FROM table

找到更多帮助here

答案 2 :(得分:1)

我使用UnitE,这就是我用来从人员表中动态选择列的方法。

INFORMATION_SCHEMA.COLUMNS存储表的列列表,并以此为基础构建SELECT语句。

Declare @Columns NVARCHAR(MAX)
Declare @Table varchar(15) = 'capd_person'

SELECT @Columns=COALESCE(@Columns + ',', '') + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (TABLE_NAME=@Table )  

EXEC('SELECT DISTINCT ' + @Columns + ' FROM ' + @Table)

您需要按照前面所述使用CONCAT更改EXEC命令以适合您的需求。

答案 3 :(得分:0)

JonTout答案的改进版本:

    Declare @Columns NVARCHAR(MAX)
    Declare @Table varchar(15) = 'TableName'

    SELECT @Columns=COALESCE(@Columns + '+', '') +'CONVERT(varchar(max),ISNULL('+ COLUMN_NAME+',''''))+''-'''
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE (TABLE_NAME=@Table ) 


    EXEC('SELECT ' + @Columns + ' FROM ' + @Table)