SQL - 根据值创建多个列

SQL - Creating multiple columns based on value

我以前从未发过帖子所以

  1. SQL新手在此
  2. 希望格式正确

我一直在努力寻找一种方法来操纵这些数据,但还没有找到我认为满足我需要的方法。我需要根据另一列的值创建额外的列(在我的例子中,基于 Observation 列)

PID | Observation_Date | Observation_Time | Obs_Value | Observation

1424285941000610    | 20050603  | 115459    | 110   mm Hg   |BP Systolic  
1424285941000610    | 20050603  | 115459    | 80    mm Hg   |BP Diastolic  
1424285941000610    | 20050603  | 115459    | N             |Smoking Status  
1424285941000610    | 20050912  | 141308    | 110   mm Hg   |BP Systolic  
1424285941000610    | 20050912  | 141308    | 86    mm Hg   |BP Diastolic  
1424285941000610    | 20051027  | 104202    | 195   lb      |Weight  
1424285941000610    | 20051027  | 104202    | 104   mm Hg   |BP Systolic  
1424285941000610    | 20051027  | 104202    | 70    mm Hg   |BP Diastolic  
1424285941000610    | 20060629  | 092852    | 61.5  in      |Height  
1424285941000610    | 20060629  | 092852    | 209   lb      |Weight  

我已经设法解决了我希望如何使用多个 case 语句,但我得到的结果如下所示:

PID Obs_Date    |Obs_Time   |smoking status |bp_dia |bp_sys |Height |Weight  
1424285963050610    |20121203   |161415     |NULL   |NULL   |NULL   |180lb  
1424285963050610    |20121203   |161415     |NULL   |NULL   |70in   |NULL    
1424285963050610    |20121203   |161415     |NULL   |138mm Hg   |NULL   |NULL  
1424285963050610    |20121203   |161415     |80mm Hg    |NULL   |NULL   |NULL 

这在技术上可以满足我的需要,但我知道它不正确,所以我希望我能让它看起来像下面这样,其中根据观察日期组合了行

理想情况下,它看起来像这样:

PID |Obs_Date |Obs_Time |smoking status |bp_dia |bp_sys |Height |Weight

1424285963050610    |20121203   |161415     |N  |80 mmHg  |110 mmHg  |null |null

我也尝试过使用嵌套替换,但我最终遇到了同样的问题,因为它都在一个列中。

我正在使用 SQL server 2008。任何帮助是极大的赞赏。

有几种方法可以做到这一点。 一种是通过相关子查询 select 数据。 另一种是 table 值子查询。 另一种方法是仅按三个关键字段分组并执行最小值并处理空值。 我将在下面显示 table 有价值的选项。 你可以看到我已经将主要患者数据与每个观察结果分开,因为它是自己的数据集。然后将它们链接到 3 个关键字段。

SELECT 
   pd.PID, pd.Observation_Date, pd.Observation_Time,
   ss.Obs_Value,
   bpd.Obs_Value,
   bps.Obs_value,
   h.Obs_Value,
   w.Obs_Value
FROM (SELECT DISTINCT PID, Observation_Date, Observation_Time FROM patient_data) AS pd
     LEFT OUTER JOIN (SELECT PID, Observation_Date, Observation_Time, Obs_Value FROM patient_data WHERE Observation = 'Smoking Status') AS ss ON (pd.PID = ss.PID AND pd.Observation_Date = ss.Observation_Date AND pd.Observation_Time = ss.Observation_Time)
     LEFT OUTER JOIN (SELECT PID, Observation_Date, Observation_Time, Obs_Value FROM patient_data WHERE Observation = 'BP Diastolic') AS bpd ON (pd.PID = bpd.PID AND pd.Observation_Date = bpd.Observation_Date AND pd.Observation_Time = bpd.Observation_Time)
     LEFT OUTER JOIN (SELECT PID, Observation_Date, Observation_Time, Obs_Value FROM patient_data WHERE Observation = 'BP Systolic') AS bps ON (pd.PID = bps.PID AND pd.Observation_Date = bps.Observation_Date AND pd.Observation_Time = bps.Observation_Time)
     LEFT OUTER JOIN (SELECT PID, Observation_Date, Observation_Time, Obs_Value FROM patient_data WHERE Observation = 'Height') AS h ON (pd.PID = h.PID AND pd.Observation_Date = h.Observation_Date AND pd.Observation_Time = h.Observation_Time)
     LEFT OUTER JOIN (SELECT PID, Observation_Date, Observation_Time, Obs_Value FROM patient_data WHERE Observation = 'Weight') AS w ON (pd.PID = w.PID AND pd.Observation_Date = w.Observation_Date AND pd.Observation_Time = w.Observation_Time)

这是一个可能是首选解决方案的示例,它只是分组并取最大值。

SELECT
   pd.PID, pd.Observation_Date, pd.Observation_Time,
   MAX(CASE WHEN pd.Observation = 'Smoking Status' THEN pd.Obs_Value ELSE '' END) AS [smoking status],
   MAX(CASE WHEN pd.Observation = 'BP Diastolic' THEN pd.Obs_Value ELSE '' END) AS [bp_dia],
   MAX(CASE WHEN pd.Observation = 'BP Systolic' THEN pd.Obs_Value ELSE '' END) AS [bp_sys],
   MAX(CASE WHEN pd.Observation = 'Height' THEN pd.Obs_Value ELSE '' END) AS [Height],
   MAX(CASE WHEN pd.Observation = 'Weight' THEN pd.Obs_Value ELSE '' END) AS [Weight]
FROM patient_data
GROUP BY pd.PID, pd.Observation_Date, pd.Observation_Time

所有这些都是空气代码,未经测试。