2015-01-13 11 views
6

Mam jedną do wielu tabel mapowania wyświetlanych jak poniżej. Muszę wyświetlić ICD10 POZIOME. dla każdego ICD9. Dane są dynamiczne, dlatego nie mogę korzystać ze statycznej funkcji obrotu.Wyświetlanie od poziomu do pionu za pomocą funkcji Dynamic Pivot

ICD9 | ICD10 
-----+------ 
0156 | 0178 
0156 | 0179 
| 0181 
0152 | 0202 
0231 | 0210 
0231 | 0211 
0231 | 0212 

Chcę wynik ma być wyświetlany as-

ICD9 | ICD10 | ICD10 | ICD10 
0156 | 0178 | 0179 | null 
| 0181 | null | null 
0152 | 0202 | null | null 
0231 | 0210 | 0211 | 0212 

Obecnie Próbowałem użyć tego kodu:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(icd10) 
      FROM mv_icd 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT icd9, ' + @cols + ' from 
      (
       select icd9,icd10 from mv_icd 
      ) x 
      pivot 
      (
       min(icd9) 
       for icd10 in (' + @cols + ') 
      ) p ' 
      execute(@query) 

ale to nie działa jak mam zbyt wiele rekordów (około 12000). Jak mogę zmienić kod wyświetlający ICD10 dla każdego ICD9 w kolumnie?

+0

Jeśli próbujesz przestawić 12000 kolumn, nie będziesz w stanie. Sugerowałbym, żeby zrobić coś wewnątrz aplikacji zamiast w SQL. Jaka jest maksymalna liczba 'icd10', którą będziesz mieć dla każdego' icd9'? – Taryn

Odpowiedz

5

Na podstawie bieżącego kodu przeliczasz wszystkie 12000 wartości w kolumnie ICD10 na nowe kolumny. To jest o wiele za dużo kolumn i całkowicie niemożliwe do opanowania dla każdego użytkownika.

Wygląda na to, że naprawdę chcesz przekonwertować każdą z wartości ICD10 związaną z ICD9 na nowe kolumny. Aby to zrobić, musisz użyć funkcji okienkowania, takiej jak row_number() i utworzyć unikalną wartość dla każdego ICD10, która będzie używana jako nowe nazwy kolumn.

Zapytanie zostanie użyciu coś jak:

select icd9, icd10, 
    rn = row_number() over(partition by icd9 order by icd10) 
from mv_icd 

Zobacz Demo. To daje wynik:

| ICD9 | ICD10 | RN | 
|------|-------|----| 
| 123 | 181 | 1 | 
| 152 | 202 | 1 | 
| 156 | 178 | 1 | 
| 156 | 179 | 2 | 
| 231 | 210 | 1 | 
| 231 | 211 | 2 | 
| 231 | 212 | 3 | 

masz teraz nową kolumnę rn który zawiera liczbę ICD10 wartości dla każdego ICD9. Ta nowa kolumna zostanie użyta w przestawnym, aby utworzyć nowe kolumny. Jeśli masz ograniczoną liczbę kolumn, można ciężko kodować zapytanie:

select icd9, [1], [2], [3] 
from 
(
    select icd9, icd10, 
    rn = row_number() over(partition by icd9 order by icd10) 
    from mv_icd 
) d 
pivot 
(
    max(icd10) 
    for rn in ([1], [2], [3]) 
) piv; 

Zobacz SQL Fiddle with Demo. Teraz, jeśli nie wiesz, ile łącznej liczby ICD10 elementów będzie dla każdego ICD9, będziesz musiał użyć dynamicznego SQL. chcesz zmienić swój kod w pierwotnym zapytaniu być:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

-- get list of the unique # of ICD10's per ICD9 
SET @cols = STUFF((SELECT ',' + QUOTENAME(rn) 
      FROM 
      (
       SELECT rn = row_number() over(partition by icd9 order by icd10) 
       FROM mv_icd 
      ) d 
      GROUP BY rn 
      ORDER BY rn 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
     = 'SELECT icd9, ' + @cols + ' 
      from 
      (
      select icd9, icd10, 
       rn = row_number() over(partition by icd9 order by icd10) 
      from mv_icd 
      ) x 
      pivot 
      (
      max(icd10) 
      for rn in (' + @cols + ') 
      ) p ' 

exec sp_executesql @query; 

Zobacz SQL Fiddle with Demo. Dają one efekt końcowy:

| ICD9 | 1 |  2 |  3 | 
|------|-----|--------|--------| 
| 123 | 181 | (null) | (null) | 
| 152 | 202 | (null) | (null) | 
| 156 | 178 | 179 | (null) | 
| 231 | 210 | 211 | 212 | 

Teraz można zmieniać nazwy kolumn końcowych, co trzeba, ale to powinno dać wynik, który chcesz bez tworzenia 12000 kolumny.