2013-10-01 6 views
0

Все я следующие два определения таблицыДинамическая вставка с Pivot

CREATE TABLE ICD ([EpiNum] varchar(4), [ICDCode] varchar(4)); 
GO 
INSERT INTO ICD ([EpiNum], [ICDCode]) 
VALUES 
    ('1', 'A1'), 
    ('1', 'A2'), 
    ('1', 'A3'), 
    ('2', 'B1'), 
    ('2', 'B2'), 
    ('3', 'C3'); 
GO 

CREATE TABLE TempEpisode ([EpiNum] varchar(4), [X1] varchar(4), [X2] varchar(4), [X3] varchar(4)); 
GO 
INSERT INTO TempEpisode ([EpiNum], [X1], [X2], [X3]) 
VALUES 
    ('1', '', '', ''), 
    ('2', '', '', ''), 
    ('3', '', '', ''); 
GO 

Я хочу знать, как я могу обновить TempEpisode так что я получаю

('1', 'A1', 'A2', 'A3'), 
    ('2', 'B1', 'B2', ''), 
    ('3', 'C3', '', ''); 

как выход? Обратите внимание, что есть 3 кода для EpiNum 1, 2 для EpiNum 2, 1 для EpiNum 3. Поэтому я хочу сгруппировать эти дубликаты по столбцам.

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

DECLARE @cols AS NVARCHAR(MAX), @columns AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) 
SELECT @cols = STUFF((SELECT ',' + QUOTENAME(ICDCode) 
        FROM ICD 
        GROUP BY ICDCode 
        ORDER BY ICDCode 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,''); 
PRINT @cols; 

SELECT @columns = 
    STUFF((SELECT ', coalesce(' + 
       QUOTENAME(ICDCode)+', '''') as ' + 
       QUOTENAME('X' + ICDCode) 
      FROM ICD 
      GROUP BY ICDCode 
      ORDER BY ICDCode 
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

SET @query = 'SELECT EpiNum, ' + @columns + ' 
       FROM 
       (
       SELECT EpiNum, ICDCode, ICDCode AS flag 
       FROM ICD 
      ) AS x 
       PIVOT 
       (
       MAX(flag) 
       FOR ICDCode IN (' + @cols + ') 
      ) AS p '; 
execute(@query); 

Это дает:

EpiNum XA1 XA2 XA3 XB1 XB2 XC3 
1  A1 A2 A3 
2      B1 B2 
3        C3 

Я хочу

EpiNum XA1 XA2 XA3 
1  A1 A2 A3 
2  B1 B2 
3  C3 

ответ

1

Попробуйте это

insert TempEpisode 
select * 
from 
( 
    select *, ROW_NUMBER() over (partition by epinum order by icdcode) rn 
    from ICD 
) p 
pivot (max(icdcode) for rn in ([1],[2],[3])) p2 

вещи, которые вы должны рассмотреть.

  1. Как вы определяете порядок эпизодов - есть ли дополнительное поле, которое не отображается?
  2. Это хорошая идея - почему вы де-нормализуете свои данные?
+0

Q2. Я попробую это в ближайшее время. Это для проекта хранилища данных и нормализации базы данных в этом случае для нас не важно. Нам в основном даются тонны дрянных данных, и иногда нам нужно полностью переформатировать, чтобы получить то, что нам нужно для предстоящих манипуляций, чтобы втянуться в другую базу данных с ненормализацией. – MoonKnight

+0

Q1. Ну, как вы, наверное, догадались, что это был тонкий тест. Реальные данные обширны. Порядок эпизодов будет организован через группу по порядку по запросу в поле даты. Затем, (надеюсь), используя ваш пример, я смогу нажать icdcodes в столбцы другой таблицы. – MoonKnight

+0

Спасибо за ваше время. Это очень ценится. – MoonKnight

Смежные вопросы