Динамический свод с изменяющимися столбцами

У меня есть динамическая сводка кода POA, которая извлекает данные из временной таблицы DX и вставляет данные в временную таблицу POA.
У меня проблема в том, что существует возможность вернуть до 35 различных столбцов. В зависимости от месяца может быть 15 столбцов (POA1...POA15) или там может быть все 35 столбцов (POA1...POA35). Я присоединяюсь к этой динамической сводной временной таблице на другом столе пациента. Моя проблема заключается в том, что мне нужно показать все 35 столбцов, даже если некоторые столбцы не существуют в таблице временных POA.

--Pivot DX POA Codes
DECLARE @POANAME VARCHAR(40)
SELECT @POAName = '##tmpPOA'

DECLARE @colsPOA NVARCHAR(2000)

SELECT @colsPOA = STUFF((SELECT DISTINCT TOP 100 PERCENT 
    '],[' + 'POA' + CAST(Dx.RowNum AS NVARCHAR)
    FROM #tmpDX DX
    ORDER BY '],[' + 'POA' + CAST(Dx.RowNum AS NVARCHAR)
    FOR XML PATH ('')
    ),1,2,'') + ']'

DECLARE @queryPOA NVARCHAR(4000)

SET @queryPOA = 'N
    SELECT
       EncObjID,
       '+ 
       @colsPOA
       +' INTO ' + POAName + '
       FROM 
       (SELECT
            Dx.EncObjID
            ,''POA'' + Dx.RowNum AS RowNum
            ,Dx.POAMne
        FROM #tmpDx Dx
       ) p
       PIVOT
           (
            MIN([POAMne])
            FOR RowNum IN
            ( ' + @colsPOA + ' )
           ) AS pvt'
EXECUTE(@queryPOA)

Я получаю неверное имя столбца в запросе пациента, потому что некоторые столбцы не существуют в ##tmpPOA, Я думал о создании временной таблицы под названием #tmpDxPOA и делает вставку (Insert Into #tmpDxPOA select * from ##tmpPOA), но это не работает (я получаю имя столбца или количество предоставленных значений не соответствует ошибке).

Любые мысли о том, как создать все 35 столбцов, даже если нет никаких данных? Мне все равно, если они нулевые, мне просто нужно, чтобы эти заполнители были в основном запросе пациента, и не помогает, что число возвращаемых столбцов меняется каждый месяц.

2 ответа

Решение

С помощью @mxix я смог придумать следующее:

DECLARE @POASQL NVARCHAR(MAX) 
SET @POASQL = N'INSERT INTO #tmpPOAFinal (EncObjID,'+@colsPOA+') SELECT * FROM ##tmpPOA' 
EXECUTE(@POASQL) 

Я положил это после EXECUTE(@queryPOA) в моем основном запросе.

Чтобы это работало с динамическим SQL, строки / столбцы должны существовать более нуля. Будь то для одного или нескольких пациентов. Я попытался бы развернуть число возможностей POA сразу же, а затем оставить внешнее соединение, чтобы вернуть действительные значения.

IF OBJECT_ID('tempdb..#tmpPOA') IS NOT NULL DROP TABLE #tmpPOA
CREATE TABLE #tmpPOA (POA varchar(10)) 

IF OBJECT_ID('tempdb..#tmpPatient') IS NOT NULL DROP TABLE #tmpPatient
CREATE TABLE #tmpPatient (Patient varchar(15))
INSERT INTO #tmpPatient VALUES ('ABC123'),('ABC456'),('ABC789')


DECLARE @POAFlag as INT = 0

WHILE @POAFlag <36
BEGIN
INSERT INTO #tmpPOA
VALUES('POA' +CONVERT(varchar,@POAFlag))
SET @POAFlag = @POAFlag + 1

END
SELECT * FROM #tmpPOA
CROSS JOIN #tmpPatient

Это должно раскрыть все возможности 35DX-кодов, чтобы вы могли получить их флаг POA.

Другие вопросы по тегам