首页 > 解决方案 > 将一列的多行转换为多列(动态)

问题描述

我已经四处寻找解决我的问题的方法,但它们似乎都涉及看似复杂的方法,如数据透视表、交叉表等。似乎必须有一个更简单的解决方案来解决我认为没有的问题成为一个特别复杂的问题。我正在使用 MS SQL server 2014(64 位)和 MS Report Builder 版本 3。(我的操作系统是 NT 6.3)。我们有一个包含大量表的关系数据库(这里列出的太多了),但我下面的代码给出了相关的。

目前,我正在使用该STUFF...FOR XML PATH方法将患者诊断从多行连接到一行。我想做的是每个诊断找到一列(老板想在Excel中做一些后处理,他想要这种格式)。诊断数是介于 0 和 5(含)之间的不确定数字。

我的输出是这样的(这非常简化 - 实际上有 10 列,但它说明了这一点):

Patient  Diagnoses
ID1      C32.1,HN02
ID2      C13.9
ID3      C11.9,HN04
ID4      C08.9,HN08
ID5      C80,XX01,BR22
ID6       

没有任何连接,输出是这样的:

Patient  Diagnoses
ID1      C32.1
ID1      HN02
ID2      C13.9
ID3      C11.9
ID3      HN04
ID4      C08.9
ID4      HN08
ID5      C80
ID5      XX01
ID5      BR22
ID6       

我想要的输出是这样的:

Patient  Diagnosis1  Diagnosis2  Diagnosis3 Diagnosis4
ID1      C32.1       HN02
ID2      C13.9
ID3      C11.9       HN04
ID4      C08.9       HN08
ID5      C80         XX01        BR22
ID6       

我正在使用的代码(基本上)是这样的:

SET transaction isolation level read uncommitted;

SELECT top (1000)
p.PatientId
,'Diagnoses'= STUFF((
        SELECT DISTINCT
        ',' + LTRIM(RTRIM(diag.DiagnosisCode))

        FROM
            Diagnosis diag
            INNER JOIN CourseDiagnosis cd on (cd.DiagnosisSer=diag.DiagnosisSer and cd.CourseSer=c.CourseSer)

        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

FROM
Patient p
INNER JOIN Course c on p.PatientSer=c.CourseSer

有没有人有什么好主意?

标签: sqlsql-servertsql

解决方案


我会使用条件聚合来做到这一点,但关键是row_number()

SELECT patientId,
       MAX(CASE WHEN seqnum = 1 THEN DiagnosisCode END) as DiagnosisCode_1,
       MAX(CASE WHEN seqnum = 2 THEN DiagnosisCode END) as DiagnosisCode_2,
       MAX(CASE WHEN seqnum = 3 THEN DiagnosisCode END) as DiagnosisCode_3,
       MAX(CASE WHEN seqnum = 4 THEN DiagnosisCode END) as DiagnosisCode_4
FROM (SELECT p.patientId, d.DiagnosisCode,
             ROW_NUMBER() OVER (PARTITION BY p.patientId ORDER BY d.DiagnosisCode) as seqnum
      FROM Patient p JOIN
           Course c 
           ON p.PatientSer = c.CourseSer JOIN
           CourseDiagnosis cd 
           ON cd.CourseSer = c.CourseSer JOIN
           Diagnosis d
           ON cd.DiagnosisSer = d.DiagnosisSer
     ) d
GROUP BY patientId;

推荐阅读