4

メンタルヘルス組織で Microsoft SQL Server 2008 を使用しています。

すべてのクライアントとその診断を一覧表示するテーブルがありますが、クライアントが持っている各診断は新しい行にあります。それらすべてを、各診断の日付とともに横に並べて 1 行に並べて表示したいと考えています。診断が 1 つしかない人もいれば、20 人もいる人もいれば、まったくない人もいます。

これは、私のデータの種類が現在どのように見えるかの例です (非常に少数のクライアントのみで、数千あります): http://i.imgur.com/pBV4svz.png

そして、これが私が最終的に望んでいるフォーマットです: http://i.imgur.com/8cM2iNa.png

あなたが提供できる解決策や正しい方向へのヒントは素晴らしいでしょう、ありがとう!

4

4 に答える 4

5

結果を得るには、まずピボットを解除してから、データをピボットします。アンピボットは、日付と診断の列を取得し、それらを行に変換します。データが行になったら、ピボットを適用できます。

値の数がわかっている場合は、次のようなクエリをハードコーディングできます。

select *
from
(
  select person, [case#], age,
    col+'_'+cast(rn as varchar(10)) col,
    value
  from
  (
    select person, 
      [case#],
      age,
      diagnosis,
      convert(varchar(10), diagnosisdate, 101) diagnosisDate,
      row_number() over(partition by person, [case#]
                        order by DiagnosisDate) rn
    from yourtable
  ) d
  cross apply
  (
    values ('diagnosis', diagnosis), ('diagnosisDate', diagnosisDate)
  ) c (col, value)
) t
pivot
(
  max(value)
  for col in (diagnosis_1, diagnosisDate_1,
              diagnosis_2, diagnosisDate_2,
              diagnosis_3, diagnosisDate_3,
              diagnosis_4, diagnosisDate_4)

) piv;

SQL Fiddle with Demoを参照してください。

各ケースの診断値の数は不明であると仮定します。その場合は、動的 SQL を使用して結果を生成する必要があります。

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

select @cols = STUFF((SELECT  ',' + QUOTENAME(col+'_'+cast(rn as varchar(10))) 
                    from 
                    (
                      select row_number() over(partition by person, [case#]
                                                order by DiagnosisDate) rn
                      from yourtable
                    ) t
                    cross join 
                    (
                      select 'Diagnosis' col union all 
                      select 'DiagnosisDate'
                    ) c
                    group by col, rn
                    order by rn, col
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT person, 
                    [case#],
                    age,' + @cols + '  
             from
             (
                select person, [case#], age,
                  col+''_''+cast(rn as varchar(10)) col,
                  value
                from
                (
                  select person, 
                    [case#],
                    age,
                    diagnosis,
                    convert(varchar(10), diagnosisdate, 101) diagnosisDate,
                    row_number() over(partition by person, [case#]
                                      order by DiagnosisDate) rn
                  from yourtable
                ) d
                cross apply
                (
                  values (''diagnosis'', diagnosis), (''diagnosisDate'', diagnosisDate)
                ) c (col, value)
            ) t
            pivot 
            (
                max(value)
                for col in (' + @cols + ')
            ) p '

execute(@query);

SQL Fiddle with Demoを参照してください。両方のクエリの結果は次のとおりです。

| PERSON |  CASE# | AGE |   DIAGNOSIS_1 | DIAGNOSISDATE_1 |      DIAGNOSIS_2 | DIAGNOSISDATE_2 |        DIAGNOSIS_3 | DIAGNOSISDATE_3 |  DIAGNOSIS_4 | DIAGNOSISDATE_4 |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   John |  13784 |  56 |    Depression |      03/13/2012 |     Brain Injury |      03/14/2012 | Spinal Cord Injury |      03/15/2012 | Hypertension |      03/16/2012 |
|   Kate |   2643 |  37 |       Bipolar |      03/11/2012 |     Hypertension |      03/12/2012 |             (null) |          (null) |       (null) |          (null) |
|  Kevin | 500934 |  25 | Down Syndrome |      03/18/2012 | Clinical Obesity |      03/19/2012 |             (null) |          (null) |       (null) |          (null) |
|   Pete | 803342 |  34 |  Schizophenia |      03/17/2012 |           (null) |          (null) |             (null) |          (null) |       (null) |          (null) |
于 2013-04-04T16:13:37.500 に答える
0

機密性の高い医療情報を扱っているため、識別可能な情報 (名前、年齢など) を医療情報と同じテーブルに格納しないでください。また、個人情報を独自のテーブルと personID 外部キーを持つ診断テーブルに抽出すると、必要な 1 対多の関係を確立できます。

于 2013-04-04T16:04:46.283 に答える
0

動的 SQL を使用しない限り、PIVOT 演算子はここでは機能しません。患者さんはいつ来てもいいと思います。PIVOT 演算子は、定義済みの有限数の列を操作します。動的 SQL を使用して PIVOT テーブルを作成するか、Excel や SSRS などのレポート ツールを使用してピボット レポートを作成するかを選択できます。

動的 SQL オプションは、ここでは実用的ではないと思います。患者の訪問日ごとに何百もの列が存在する可能性があるからです。

とにかく動的 SQL オプションを調べたい場合は、こちらをご覧ください。

https://www.simple-talk.com/blogs/2007/09/14/pivots-with-dynamic-columns-in-sql-server-2005/

于 2013-04-04T16:13:50.477 に答える