如何优化基于映射表遍历多视图的T-SQL动态查询?
优化多视图列数据聚合的T-SQL动态查询
我们有一张映射表MappingTable,记录了视图与列的对应关系,结构和数据如下:
| Id | ViewName | ViewColumnName |
|---|---|---|
| 1 | vwCars | MotorType |
| 2 | vwCars | FourWheelDrive |
| 3 | vwCars | TransmissionType |
| 4 | vwBikes | MotorType |
| 6 | vwBikes | TransmissionType |
| 7 | vwQuads | MotorType |
| 9 | vwQuads | FourWheelDrive |
| 16 | vwQuads | TransmissionType |
原本通过WHILE循环遍历生成UNION语句来获取所有非空列值,虽能正常运行,但在效率和代码简洁性上有优化空间,以下是几种更优实现方式:
方案一:使用STRING_AGG(SQL Server 2017及以上版本)
无需循环,直接通过字符串聚合函数一次性生成动态SQL,代码简洁高效:
DECLARE @sql NVARCHAR(MAX); SELECT @sql = STRING_AGG( 'SELECT DISTINCT CAST(' + QUOTENAME(ViewColumnName) + ' AS NVARCHAR(80)) AS Bezeichnung FROM ' + QUOTENAME(ViewName) + ' WHERE ' + QUOTENAME(ViewColumnName) + ' IS NOT NULL', ' UNION ' ) FROM MappingTable; PRINT @sql; -- EXEC sp_executesql @sql;
这里用QUOTENAME给视图名和列名添加方括号,避免名称含特殊字符导致语法错误;STRING_AGG自动处理UNION拼接,无需额外判断最后一条是否加UNION。
方案二:兼容低版本SQL Server(用FOR XML PATH)
若你的SQL Server版本低于2017,可通过FOR XML PATH实现字符串拼接:
DECLARE @sql NVARCHAR(MAX); SELECT @sql = STUFF( ( SELECT ' UNION SELECT DISTINCT CAST(' + QUOTENAME(ViewColumnName) + ' AS NVARCHAR(80)) AS Bezeichnung FROM ' + QUOTENAME(ViewName) + ' WHERE ' + QUOTENAME(ViewColumnName) + ' IS NOT NULL' FROM MappingTable FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 7, '' -- 移除开头多余的UNION及换行 ); PRINT @sql; -- EXEC sp_executesql @sql;
STUFF函数用于清理拼接后开头的无效UNION字符串,保证SQL语法正确。
原代码的弊端说明
原WHILE循环方式存在以下问题:
- 循环过程中多次单独查询
MappingTable(每次循环查三次),数据量较大时效率低下 - 需要额外处理Id间隔问题,逻辑冗余
- 代码可读性差,维护成本高
内容的提问来源于stack exchange,提问作者user2463808
相关产品推荐
相关产品推荐

