SQL - 将具有编码文本值的行转换/转置为列

标签 sql ms-access pivot pivot-table transpose

我正在寻求帮助,将数据存储在行中的表转换为存储在表中的数据。

背景...我正在处理包含入院数据的表。我们将该表称为“住院患者”。

数据当前格式为包含 3 列和 n 行的表格。这 3 列包含以下数据:

  • “Patient_ID” = 唯一的患者/个人标识符。将此视为患者的名字;
  • “Event_ID” = 唯一入场事件标识符。识别医院中独特的护理事件;
  • “Diagnosis_Code” = ICD-10 code用于记录患者住院的原因。

    对于单个患者 (Patient_ID),每次 住院 (Event_ID) 由表中的一行或多行 表示,其中一行用于每次住院在给定的住院期间记录的诊断。

    因此,任何特定的住院时间都可以由表中的一行(一个记录的诊断)或表中的多行(与多个诊断相关)来捕获。

    下面给出了当前“住院患者”表的示例...

    -------------------------------------------
    Patient_ID |  Event_ID   |  Diagnosis_Code
    -------------------------------------------
    Pers001    | HospStay001 |     C139
    Pers001    | HospStay001 |     I245
    Pers001    | HospStay001 |     D456
    Pers001    | HospStay002 |     C139
    Pers001    | HospStay002 |     J123
    Pers555    | HospStay001 |     D312
    Pers999    | HospStay001 |     C120
    Pers999    | HospStay001 |     E101
    

    这是我真正想做的:我想转换数据,以便对于每个患者的每次住院时间只有一行,以便上述表格格式如下:

    ----------------------------------------------------------------------------------------------------
    Patient_ID |  Event_ID   | Diagnosis_Code_1 | Diagnosis_Code_2 | Diagnosis_Code_3 | Diagnosis_Code_n
    ----------------------------------------------------------------------------------------------------
    Pers001    | HospStay001 |       C139       |       I245       |       D456       |
    Pers001    | HospStay002 |       C139       |       J123       |                  |
    Pers555    | HospStay001 |       D312       |                  |                  |
    Pers999    | HospStay001 |       C120       |       E101       |                  |
    

    我怀疑该解决方案需要一些动态 sql...恐怕这不是我的优势之一。

    谢谢!

  • 最佳答案

    CREATE  table #source (Patient_ID varchar(100), Event_ID varchar (100) ,Diagnosis_Code VARCHAR(100),Dig_Number INT)
    insert into #source (Patient_ID, Event_ID,Diagnosis_Code,Dig_Number) values
    ('Pers001','HospStay001','I245',2),
    ('Pers001','HospStay001','D456',3),
    ('Pers001','HospStay002','C139',1),
    ('Pers001','HospStay002','J123',2),
    ('Pers555','HospStay001','D312',1),
    ('Pers999','HospStay001','C120',1),
    ('Pers999','HospStay001','E101',2),
    ('Pers001','HospStay001','C139',1)
    
    
    --DROP TABLE tempdb..#source
    
    
    DECLARE @cols AS NVARCHAR(MAX),
            @query AS NVARCHAR(MAX)
    
    SELECT @cols = STUFF
            (
              (
                SELECT ',' + QUOTENAME( CONVERT(VARCHAR(10),Dig_Number))
                FROM #source
                GROUP BY Dig_Number
    
                ORDER BY Dig_Number
                FOR XML PATH(''), TYPE
              ).value('.', 'NVARCHAR(MAX)'),
              1,1,''
            );
    
    SET @query = 'SELECT Patient_ID,Event_ID,' + @cols + ' 
                  FROM
                  (
                    SELECT Patient_ID,Event_ID,Diagnosis_Code,dig_number
                    FROM #source
                 ) x
                 PIVOT
                 (
                    MAX(Diagnosis_Code)
                    FOR Dig_Number IN (' + @cols + ')
                 ) p ';
    
    EXECUTE(@query);
    

    如果再增加一列,即 diaosis 编号,就可以了。

    关于SQL - 将具有编码文本值的行转换/转置为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50264415/

    相关文章:

    php - 如何存储配置?

    sql - Mysql 性能和 Count(*)

    c# - 如何将数据插入 Microsoft Access 数据库?

    C# enctypted .accdb 连接

    sql - 连接操作中的语法错误

    c# - 使用 Linq 的数据透视表

    mysql - 列到行查询

    mysql - 数据表 - 从不同的 Laravel 查询创建每一列

    mysql - 从 MySQL 表中删除两个字段相同的重复项

    sql - 什么会提供更好的性能,每个表或全局的专用 pgsql 触发器函数?