假设我有一行数据,存储如下:
------------------------
| Col 1 | Col 2 | Col 3 |
|------------------------|
| Foo | Bar | Foobar |
我该如何将其隐藏为单个字符串,如下所示?
Foo-Bar-Foobar
此表中的列标题(和列标题数)未知,因此按列名进行选择不是一个选项(?)。
请注意,我并不是要在列中合并值列表,而是在一行中合并值存储。我还希望避免使用数据透视,因为我将处理大量数据,并且不想影响性能。
答案 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
来创建一个易俗气的样本ELEMENTS XSINIL
,以强制引擎不要忽略NULL值。您可以尝试在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)