从动态sql中选择NOTNULL列作为逗号分隔的字符串
我正在尽力避免使用游标。nvarchar变量中有一个逗号分隔的列列表,如下所示:从动态sql中选择NOTNULL列作为逗号分隔的字符串,sql,sql-server,tsql,sql-server-2016,dynamic-sql,Sql,Sql Server,Tsql,Sql Server 2016,Dynamic Sql,我正在尽力避免使用游标。nvarchar变量中有一个逗号分隔的列列表,如下所示: @columnList = 'col1,col2,col5' 有一个包含许多varchar列的表: myTable: [col1],[col2],[col3],[col4],[col5],[col6],[col7] 以下是我使用动态sql选择数据的方式: exec ('select ' + @columnList + ' from myTable') 此查询返回以下结果: [col1], [col2] , [
@columnList = 'col1,col2,col5'
有一个包含许多varchar列的表:
myTable: [col1],[col2],[col3],[col4],[col5],[col6],[col7]
以下是我使用动态sql选择数据的方式:
exec ('select ' + @columnList + ' from myTable')
此查询返回以下结果:
[col1], [col2] , [col5]
null , "txt1" , null
"txt2", null , null
null , "txt3" , "txt4"
这就是我需要得到的:
@resultList = "txt1,txt2,txt3,txt4"
如何选择仅包含非空值的逗号分隔字符串?我知道如何将表转换为逗号分隔的字符串,因此得到如下结果:
[column]
"txt1"
"txt2"
"txt3"
"txt4"
也可以。有什么建议吗?请随意推荐一种基本方法,我不希望您为我编写实际的代码。您可以使用如下解决方案,只需使用一个来创建SQL查询:
DECLARE @columnList VARCHAR(100)
SET @columnList = 'col1,col2,col5'
SET @columnList = REPLACE(@columnList, ',', ' AS colName FROM myTable UNION ALL SELECT ');
EXEC('SELECT * FROM (SELECT ' + @columnList + ' AS colName FROM myTable)t WHERE NOT t.colName IS NULL');
您还可以使用以下解决方案:
既然您提到您已经知道如何聚合为逗号分隔的,下面介绍如何使用交叉应用取消分割表格:
select unpivoted.*
from myTable
cross apply
( values
('col1',col2)
,('col2',col2)
,('col3',col3) -- etc
)unpivoted(colname,colval)
这适用于SQL Server 2017,在早期版本
STRING\u AGG
上,用法应替换为
您可以先将结果连接成一行,然后使用STRING\u AGG
将它们聚合成一个字符串:
;with t as
(
SELECT * FROM (VALUES
(null , 'txt1' , null),
('txt2', null , null),
(null , 'txt3' , 'txt4')) x(col1, col2, col5)
)
SELECT STRING_AGG(STUFF(CONCAT(',' + col1, ',' + col2, ',' + col5), 1, 1, ''), ',')
FROM t
CTE仅用于展示,您只需在动态查询中执行即可:
DECLARE @columnList NVARCHAR(MAX) = 'col1,col2,col5'
DECLARE @query NVARCHAR(MAX) = ''
SELECT @query = 'SELECT STRING_AGG(STUFF(CONCAT('','' + ' + REPLACE(@columnList, ',', ', '','' + ') + '), 1, 1, ''''), '','') from mytable'
EXEC sp_executesql @query
联合所有非空值以获得第二个选项。
exec('select'+@columnList+'from myTable')
是个坏主意。SQL注入不是您的朋友。正在使用另一个查询在服务器上生成哪个SQL server版本?@columnList
。没有人能在里面注射东西。请随意推荐一种更好的方法,比如Mssql 2016 v13.0.xWorth,它需要2017+版本。OP在评论中说,v2016正在使用中…哦,对了。。。我甚至会问他们在考虑STRING\u AGG
时到底使用了哪个版本,但我把2016年和2017年搞混了。我会在我的答案上加一条注释。
DECLARE @columnList NVARCHAR(MAX) = 'col1,col2,col5'
DECLARE @query NVARCHAR(MAX) = ''
SELECT @query = 'SELECT STRING_AGG(STUFF(CONCAT('','' + ' + REPLACE(@columnList, ',', ', '','' + ') + '), 1, 1, ''''), '','') from mytable'
EXEC sp_executesql @query