使用Dynamic Pivot Function进行水平到垂直显示

Mit*_*ora 6 sql sql-server pivot

我有一个到多个映射表,如下所示.我需要显示ICD10HORIZONTALLY.为每个人ICD9.数据是动态的,因此我不能使用静态枢轴功能.

ICD9 | ICD10
-----+------
0156 | 0178
0156 | 0179
0123 | 0181
0152 | 0202
0231 | 0210
0231 | 0211
0231 | 0212
Run Code Online (Sandbox Code Playgroud)

我希望结果显示为 -

ICD9 | ICD10 | ICD10 | ICD10
0156 | 0178  | 0179  | null
0123 | 0181  | null  | null
0152 | 0202  | null  | null
0231 | 0210  | 0211  | 0212
Run Code Online (Sandbox Code Playgroud)

目前我尝试使用此代码:

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)
Run Code Online (Sandbox Code Playgroud)

但它不起作用,因为我有太多的记录(约12000).如何更改代码以在列中显示ICD10每个代码ICD9

Tar*_*ryn 5

根据您当前的代码,您将ICD10列中的所有12000个值转换为新列.这是太多的列,并且对于任何用户来说都是完全无法管理的.

您似乎确实希望将ICD10与之关联的每个值转换ICD9为新列.为此,您需要使用类似的窗口函数,row_number()并为每个ICD10将用作新列名称的值创建唯一值.

您的查询将使用以下内容:

select icd9, icd10,
  rn = row_number() over(partition by icd9 order by icd10)
from mv_icd
Run Code Online (Sandbox Code Playgroud)

演示.这给出了一个结果:

| ICD9 | ICD10 | RN |
|------|-------|----|
|  123 |   181 |  1 |
|  152 |   202 |  1 |
|  156 |   178 |  1 |
|  156 |   179 |  2 |
|  231 |   210 |  1 |
|  231 |   211 |  2 |
|  231 |   212 |  3 |
Run Code Online (Sandbox Code Playgroud)

您现在有一个新列rn,其中包含ICD10每个列的值数ICD9.此新列将用于数据透视表以创建新列.如果您的列数有限,则可以对查询进行硬编码:

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;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.现在,如果您不知道ICD10每个项目总共有多少项,ICD9则必须使用动态SQL.您将原始查询中的代码更改为:

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;
Run Code Online (Sandbox Code Playgroud)

请参阅SQL Fiddle with Demo.这些给出了最终结果:

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

现在,您可以将最终列的名称更改为您需要的任何内容,但这样可以为您提供所需的结果,而无需创建12000列.