web-dev-qa-db-ja.com

CASEステートメントで選択SQLServer 2008 R2

CASEステートメントを使用してアカウントをスコアリングするクエリがあります。クエリは、ベクトル形式の値を探します。したがって、たとえば、私が患者である場合、複数の診断コードを持つことができますが、それらは列値として保存されない場合、次のように別の行に保存されます。

VISIT_ID | CLASFCD
123      | 196.0
123      | 197.0
123      | 198.0
321      | 199.0
321      | 650.9
222      | 111
555      | ...
...

私のクエリでは、次のようなケースステートメントを使用しています。

, CASE
    WHEN DV.ClasfCd IN (
    '196.0','196.1','196.2','196.3','196.5','196.6','196.8','196.9',
    '197.0','197.1','197.2','197.3','197.4','197.5','197.6','197.7',
    '197.8','198.2','198.3','198.4','198.5','199.1','209.7'
    )
    THEN 6
    ELSE 0
  END AS PRIN_DX_CD_5

これは、5つの異なるコードグループに対して行います。何が起こっているのかというと、これらのグループの1つで基準が満たされている場合、結果は同じ行ではなく別の行に返されます。これが私が取り戻しているデータの例です:

VISIT_ID | CC GROUP 1 | CC GROUP 2 | CC GROUP 3 | CC GROUP 4 | CC GROUP 5 | TOTAL
123      | 1          | 0          | 0          | 0          | 0          | 1
123      | 0          | 2          | 0          | 0          | 0          | 2
123      | 0          | 0          | 0          | 0          | 0          | 0

私が返したいのは次のとおりです。

VISIT_ID | CC GROUP 1 | CC GROUP 2 | CC GROUP 3 | CC GROUP 4 | CC GROUP 5 | TOTAL
123      | 1          | 2          | 0          | 0          | 0          | 3
321      | 1          | 0          | 0          | 0          | 6          | 6

最終的な合計スコアは6を超えることはできません。

いくつかの簡潔さでクエリ全体がここにあります、それはマルチパートクエリの一部です、私は元のものに変更を加えています:

SET ANSI_NULLS OFF
GO
DECLARE @SD DATETIME
DECLARE @ED DATETIME
SET @SD = '2013-01-01';
SET @ED = '2013-05-31';

-- @CM TABLE DECLARATION #############################################]
DECLARE @CM TABLE (
ENCOUNTER_ID VARCHAR(200)
, [MRN CM] VARCHAR(200)
, NAME VARCHAR(500)
, [CC GRP ONE SCORE] VARCHAR(20)
, [CC GRP TWO SCORE] VARCHAR(20)
, [CC GRP THREE SCORE] VARCHAR(20)
, [CC GRP FOUR SCORE] VARCHAR(20)
, [CC GRP FIVE SCORE] VARCHAR(20)
, [CC LACE SCORE] INT
)
--####################################################################]

INSERT INTO @CM
SELECT
C.PT_NO
, C.MED_REC_NO
, C.PT_NAME
, C.PRIN_DX_CD_1
, C.PRIN_DX_CD_2
, C.PRIN_DX_CD_3
, C.PRIN_DX_CD_4
, C.PRIN_DX_CD_5
, CASE
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 0 THEN 0
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 1 THEN 1
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 2 THEN 2
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 3 THEN 3
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 4 THEN 4
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) = 5 THEN 5
    WHEN (C.PRIN_DX_CD_1+C.PRIN_DX_CD_2+C.PRIN_DX_CD_3+C.PRIN_DX_CD_4+C.PRIN_DX_CD_5) >= 6 THEN 6
  END AS CC_LACE_SCORE

FROM (
    SELECT DISTINCT PAV.PT_NO
    , MED_REC_NO
    , PT_NAME
    , CASE
        WHEN dv.ClasfCd IN (

        )
        THEN 1
        ELSE 0
      END AS PRIN_DX_CD_1
    , CASE
        WHEN DV.ClasfCd IN (

        )
        THEN 2
        ELSE 0
    END AS PRIN_DX_CD_2
    , CASE
        WHEN DV.ClasfCd IN (

        )
        THEN 3
        ELSE 0
      END AS PRIN_DX_CD_3
    , CASE
        WHEN DV.ClasfCd IN (

        )
        THEN 4
        ELSE 0
      END AS PRIN_DX_CD_4
    , CASE
        WHEN DV.ClasfCd IN (

        )
        THEN 6
        ELSE 0
      END AS PRIN_DX_CD_5

      FROM smsdss.BMH_PLM_PtAcct_V PAV
      JOIN smsdss.BMH_PLM_PtAcct_Clasf_Dx_V DV
      ON PAV.PtNo_Num = DV.PtNo_Num

      WHERE Dsch_Date BETWEEN @SD AND @ED


)C

GROUP BY C.PT_NO
, C.MED_REC_NO
, C.PT_NAME
, C.PRIN_DX_CD_1
, C.PRIN_DX_CD_2
, C.PRIN_DX_CD_3
, C.PRIN_DX_CD_4
, C.PRIN_DX_CD_5
ORDER BY C.Pt_No

SELECT * FROM @CM

ご協力ありがとうございました、

3
MCP_infiltrator

問題は、計算された_PRIN_DX__列を集計に含めていることです。代わりに、それらを集計から削除し、0以外の値を選択します(max()を使用)。

_SELECT C.PT_NO, C.MED_REC_NO, C.PT_NAME,
       max(C.PRIN_DX_CD_1) as PRIN_DX_CD_1,
       max(C.PRIN_DX_CD_2) as PRIN_DX_CD_2,
       max(C.PRIN_DX_CD_3) as PRIN_DX_CD_3,
       max(C.PRIN_DX_CD_4) as PRIN_DX_CD_4,
       max(C.PRIN_DX_CD_5) as PRIN_DX_CD_5,
       (case when max(C.PRIN_DX_CD_1) + max(C.PRIN_DX_CD_2) + max(C.PRIN_DX_CD_3) + 
                  max(C.PRIN_DX_CD_4) + max(C.PRIN_DX_CD_5) < 6
             then max(C.PRIN_DX_CD_1) + max(C.PRIN_DX_CD_2) + max(C.PRIN_DX_CD_3) + 
                  max(C.PRIN_DX_CD_4) + max(C.PRIN_DX_CD_5)
             else 6
        end) as CC_LACE_SCORE
FROM (SELECT DISTINCT PAV.PT_NO, MED_REC_NO, PT_NAME,
             (CASE WHEN dv.ClasfCd IN ()
                   THEN 1
                   ELSE 0
              END) AS PRIN_DX_CD_1,
             (CASE WHEN DV.ClasfCd IN ()
                   THEN 2
                   ELSE 0
              END) AS PRIN_DX_CD_2
             (CASE WHEN DV.ClasfCd IN ()
                   THEN 3
                   ELSE 0
              END) AS PRIN_DX_CD_3,
             (CASE WHEN DV.ClasfCd IN ()
                   THEN 4
                   ELSE 0
              END) AS PRIN_DX_CD_4,
             (CASE WHEN DV.ClasfCd IN ()
                   THEN 6
                   ELSE 0
              END) AS PRIN_DX_CD_5   
      FROM smsdss.BMH_PLM_PtAcct_V PAV join
           smsdss.BMH_PLM_PtAcct_Clasf_Dx_V DV
           ON PAV.PtNo_Num = DV.PtNo_Num
      WHERE Dsch_Date BETWEEN @SD AND @ED
     ) C
GROUP BY C.PT_NO, C.MED_REC_NO, C.PT_NAME
ORDER BY C.Pt_No;
_

サブクエリのdistinctは必要ないかもしれませんが、それはデータが実際にどのように見えるかによって異なります。

7
Gordon Linoff

更新:

@Darren Koppが言うように、あなたは間違いなくピボットを調べる必要があります

IN句の値をグループでマップするテーブルを作成します

次に、ピボットを実行します

次に、次のようなものを使用してminimum(val, 6)するタイミングを単純化します。

CREATE FUNCTION Minimum
(@Param1 Integer, @Param2 Integer)
Returns Table As
Return(Select Case When @Param1 < @Param2 
               Then @Param1 Else @Param2 End MinValue)

したがって、テーブルのcdmapは次のようになります。

6    |    '196.0'
6    |    '196.1'
6    |    '196.2'


SELECT ....,  [1], [2], [4], [6]
FROM
(
FROM smsdss.BMH_PLM_PtAcct_V PAV
  JOIN smsdss.BMH_PLM_PtAcct_Clasf_Dx_V DV
  ON PAV.PtNo_Num = DV.PtNo_Num
  JOIN cdmap c on c.ClasfCd = dv.ClasfCd
  WHERE Dsch_Date BETWEEN @SD AND @ED
 ) AS SourceTable
 PIVOT
 (
  ...
  FOR c.ClasfCd IN ([1], [2], [4], [6])
 ) AS PivotTable;
1
vittore