2013-12-13 70 views
3

我有一個查詢使用CASE語句對帳戶計分。該查詢查找處於向量形式的值。因此,舉例來說,如果我是一個病人,我可以有多個診斷代碼,但它們不是存儲爲列值,它們存儲在另一行,像這樣:使用CASE語句選擇SQL Server 2008 R2

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

我的查詢使用案例Statment像這樣:

, 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個不同的代碼組。發生的事情是,如果符合其中一個組的標準,則結果會返回到另一行,而不是同一行。下面是我收到回數據的例子:

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 

感謝你的幫助,

+2

你看過'PIVOT'命令嗎? http://technet.microsoft.com/en-us/library/ms177410.aspx –

+0

@DarrenKopp我從來沒有使用'PIVOT'命令。會使用它阻止我從它的值中查詢它後面的查詢嗎? –

回答

7

問題是您要在聚合中包含計算的PRIN_DX_列。相反,從聚集刪除它們,只是選擇(使用max())非0值:

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,但是這取決於你的數據應該有的樣子。

+0

此更新獲得同一行上的所有分數,這很好,但由於某些原因,總列使用列中內容的最大分數,因此它不會給出停止在6處的分數的總和。返回的示例: Gropu 1 = 1,Group 2 = 2,Total = 2,應該是3,有點困惑,爲什麼它不起作用。 –

+0

這似乎已修復它。謝謝Gordon –

1

UPDATE:

你無疑需要尋找到支點作爲@Darren柯普說

創建表到自己的價值觀IN條款與組映射

然後做旋轉

然後使用類似

CREATE FUNCTION Minimum 
(@Param1 Integer, @Param2 Integer) 
Returns Table As 
Return(Select Case When @Param1 < @Param2 
       Then @Param1 Else @Param2 End MinValue) 
你的情況simpify時 minimum(val, 6)

所以你的表格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; 
+0

你能提供一個鏈接到創建一個功能的良好文檔?我從來沒有這樣做過,即使一年以來我也沒有使用過SQL,並且這些都是自學的,所以我肯定會有一些非常糟糕的做法,我不知道許多方法來簡化代碼並優化它。 –

+1

給了你一些鏈接。添加數據透視查詢的一部分開始,嘗試完成它自己。還要檢查交叉/外部適用的是什麼。 – vittore

+0

謝謝你們所有的聯繫,這對我將來會非常有幫助,當我參加期末考試時,我的學期將於週日結束,因此這將爲冬季的閱讀做好準備。 –