从动态sql中选择NOTNULL列作为逗号分隔的字符串

从动态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] , [

我正在尽力避免使用游标。nvarchar变量中有一个逗号分隔的列列表,如下所示:

@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