Применение функции к динамическим именам столбцов - PullRequest
1 голос
/ 14 июня 2019

Я хотел бы обработать результаты динамического центра, который приводит к переменным количествам столбцов данных с разными именами.Но они содержат данные, связанные друг с другом, и имеют один и тот же тип данных.Для каждого столбца результата я хотел бы применить идентичную функцию 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

Ответы [ 3 ]

1 голос
/ 14 июня 2019

Вы можете сделать это с помощью INFORMATION_SCHEMA, STUFF и Dynamic 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
0 голосов
/ 14 июня 2019

Мне не совсем нравятся решения STUFF. И поскольку сводный запрос был уже динамическим, с помощью Raka и этого ответа по теме я динамически генерировал список столбцов. Я считаю, что этот код легче понять.

Предполагая, что столбцы, сгенерированные PIVOT, находятся в @Columns TABLE (Column VARCHAR) или аналогичны:

DECLARE @Isnull NVARCHAR(MAX);

SELECT @Isnull = ISNULL(@Isnull + ', ', '') + 'ISNULL(' + QUOTENAME([Column]) + ', 0)'
FROM Columns

EXEC sp_executesql N'SELECT ' + @Isnull + 'FROM whatever PIVOT things'
0 голосов
/ 14 июня 2019

Надеюсь, что это удовлетворит ваше требование

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;


  Declare  @Main varchar(max)=''
--use INFORMATION_SCHEMA.COLUMNS for physical table 
        select  @Main += ',isnull('+name+',0) as '+name
         from (select name from tempdb.sys.columns where object_id =object_id('tempdb..#T')) as spt

        set @Main= 'select '+stuff(@Main ,1,1,'') + ' from #T'
        Exec(@Main)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...