首页 > 解决方案 > 将函数应用于动态列名

问题描述

我想处理动态数据透视的结果,这会导致不同数量的不同命名的数据列。但它们确实包含彼此相关的数据并且属于相同的数据类型。对于每个结果列,我想应用一个相同的ISNULL函数。但是由于我不知道列的名称,所以不可能逐列写出操作。

这是一个SQL Fiddle。还有一个示例表:

CREATE TABLE T (ID INT UNIQUE NOT NULL, C1 INT NULL, C2 INT NULL, C3 INT NULL);
INSERT INTO T VALUES
    (0, NULL, NULL, NULL),
    (1, 9, NULL, NULL),
    (2, NULL, 8, NULL),
    (3, NULL, NULL, 10),
    (4, 12, 61, NULL),
    (5, 36, NULL, 86),
    (6, NULL, 77, 42),
    (7, 11, 22, 33);

SELECT * FROM T;

 ID |  C1  |  C2  |  C3
----+------+------+-----
 0  | NULL | NULL | NULL
 1  |    9 | NULL | NULL
 2  | NULL |    8 | NULL
 3  | NULL | NULL |   10
 4  |   12 |   61 | NULL
 5  |   36 | NULL |   86
 6  | NULL |   77 |   42
 7  |   11 |   22 |   33

ISNULL(CN, 0)然后将为这些列中的每一个应用一个。怎么可能做到这一点?如果这有什么不同,因为数据透视查询是动态的,这个处理将在EXEC sp_executesql.

预期的输出将是:

 ID |  C1  |  C2  |  C3
----+------+------+-----
 0  |    0 |    0 |    0
 1  |    9 |    0 |    0
 2  |    0 |    8 |    0
 3  |    0 |    0 |   10
 4  |   12 |   61 |    0
 5  |   36 |    0 |   86
 6  |    0 |   77 |   42
 7  |   11 |   22 |   33

标签: sqlsql-server

解决方案


您可以在和的帮助下做到这INFORMATION_SCHEMA一点:STUFFDynamic SQL

-- Get the all columns names from the underlying table
SELECT COLUMN_NAME
INTO #TEMP
FROM [Database_Name].INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'T' AND COLUMN_NAME != 'ID'

DECLARE @COLUMNS  NVARCHAR(MAX)
DECLARE @sql NVARCHAR(MAX)

-- Construct a string with ISNULL
SELECT @COLUMNS =  STUFF((SELECT DISTINCT ',ISNULL(' + QUOTENAME(COLUMN_NAME) + ',0) ' + QUOTENAME(COLUMN_NAME) 
FROM #TEMP 
ORDER BY 1 
FOR XML PATH('')), 1, 1, '')

-- and use Dynamic SQL
SELECT @sql = 'SELECT ID,'+ @COLUMNS +' FROM T'

EXEC sp_executesql @sql

推荐阅读