Select 非空列作为来自动态 sql 的逗号分隔字符串
Select not null columns as a comma separated string from dynamic sql
我尽量避免使用游标。 nvarchar 变量中有一个逗号分隔的列列表,如下所示:
@columnList = 'col1,col2,col5'
有一个 table 有很多 varchar 列:
myTable: [col1],[col2],[col3],[col4],[col5],[col6],[col7]
这就是我 select 使用动态数据的方式 sql:
exec ('select ' + @columnList + ' from myTable')
本次查询returns结果如下:
[col1], [col2] , [col5]
null , "txt1" , null
"txt2", null , null
null , "txt3" , "txt4"
这是我需要得到的:
@resultList = "txt1,txt2,txt3,txt4"
如何 select 逗号分隔的字符串只包含非空值?我知道如何将 table 转换为逗号分隔的字符串,所以得到类似的东西:
[column]
"txt1"
"txt2"
"txt3"
"txt4"
也可以。有什么建议么?随意提出一个基本方法,我不希望你为我编写实际代码。
您可以使用如下解决方案,仅使用 REPLACE
创建 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');
您还可以使用 UNPIVOT
的解决方案:
DECLARE @columnList VARCHAR(100);
SET @columnList = 'col1,col2,col5';
EXEC('SELECT colName FROM (SELECT ' + @columnList + ' FROM myTable) t1 UNPIVOT (colName FOR columnNames IN (' + @columnList + ')) AS t2');
既然你提到你已经知道如何聚合成逗号分隔的,下面是如何使用交叉应用取消你的 table:
select unpivoted.*
from myTable
cross apply
( values
('col1',col2)
,('col2',col2)
,('col3',col3) -- etc
)unpivoted(colname,colval)
这适用于 SQL Server 2017,在早期版本 STRING_AGG
上,用法应替换为 XML-based solution。
您可以先将结果连接成一行,然后使用 STRING_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
我尽量避免使用游标。 nvarchar 变量中有一个逗号分隔的列列表,如下所示:
@columnList = 'col1,col2,col5'
有一个 table 有很多 varchar 列:
myTable: [col1],[col2],[col3],[col4],[col5],[col6],[col7]
这就是我 select 使用动态数据的方式 sql:
exec ('select ' + @columnList + ' from myTable')
本次查询returns结果如下:
[col1], [col2] , [col5]
null , "txt1" , null
"txt2", null , null
null , "txt3" , "txt4"
这是我需要得到的:
@resultList = "txt1,txt2,txt3,txt4"
如何 select 逗号分隔的字符串只包含非空值?我知道如何将 table 转换为逗号分隔的字符串,所以得到类似的东西:
[column]
"txt1"
"txt2"
"txt3"
"txt4"
也可以。有什么建议么?随意提出一个基本方法,我不希望你为我编写实际代码。
您可以使用如下解决方案,仅使用 REPLACE
创建 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');
您还可以使用 UNPIVOT
的解决方案:
DECLARE @columnList VARCHAR(100);
SET @columnList = 'col1,col2,col5';
EXEC('SELECT colName FROM (SELECT ' + @columnList + ' FROM myTable) t1 UNPIVOT (colName FOR columnNames IN (' + @columnList + ')) AS t2');
既然你提到你已经知道如何聚合成逗号分隔的,下面是如何使用交叉应用取消你的 table:
select unpivoted.*
from myTable
cross apply
( values
('col1',col2)
,('col2',col2)
,('col3',col3) -- etc
)unpivoted(colname,colval)
这适用于 SQL Server 2017,在早期版本 STRING_AGG
上,用法应替换为 XML-based solution。
您可以先将结果连接成一行,然后使用 STRING_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