簡體   English   中英

CASE語句中的計算

[英]Calculation within a CASE Statement

我試圖在我的case語句中包括第4個“程序”,它將是所有加在一起的程序的組合,因為沒有表ID可以標識所有(即pp.id = 2 + p.id = 3 + p。 id = 4 =全部)。 CASE語句能夠實現這一目標嗎? 合並? 嵌套的SELECT?

   DECLARE @date datetime = CONVERT(date, getdate())

Select Count(Distinct fm.MEMBER_ID) As 'Count',
      Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' + Cast(DatePart(MONTH,
      dd.DATE) As VARCHAR) + '/01' As DATE) As 'Month',
      Case When p.ID = 2 Then 'Program1' When p.ID = 3 Then 'Program2'
        When p.ID = 4 Then 'Program3' End As 'Program'
    From FACT_MEMBER_MONTH_START fm
      Join DIM_COVERAGE c On fm.MEMBER_ID = c.MEMBER_ID
      Join DIM_PROGRAM p On c.PROGRAM_ID = p.ID
      Join DIM_DATE dd On fm.MONTH_ID = dd.MONTH_ID
      Join DIM_MEMBER dm On fm.MEMBER_ID = dm.ID
      Join DIM_INDIVIDUAL DI On fm.MEMBER_ID = DI.ID
      Join DIM_LIVING_SITUATION dls On fm.LIVING_SITUATION_ID = dls.ID
    Where dd.DATE Between c.EFFECTIVE_DATE And c.EXPIRATION_DATE And (dls.ID = 5
        Or dls.ID = 6) and (dd.DATE between DATEADD(MM, -18, @date) and @date)
    Group By Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' +
      Cast(DatePart(MONTH, dd.DATE) As VARCHAR) + '/01' As DATE),
      Case When p.ID = 2 Then 'FC' When p.ID = 3 Then 'PACE'
        When p.ID = 4 Then 'Part' End
 ORDER BY Month desc

結果:

樣品結果

最終目標將是“第4個程序”,僅是3個程序的總和。這將在Logi Analytics中用於根據一個查詢開發多個圖表,這些查詢可以使用這些單獨的程序進行過濾。

關於UNION ALL,將您的Program1,Program2,Program3放在一起並為Program4添加新行怎么樣

   DECLARE @date datetime = CONVERT(date, getdate())

Select Count(Distinct fm.MEMBER_ID) As 'Count',
      Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' + Cast(DatePart(MONTH,
      dd.DATE) As VARCHAR) + '/01' As DATE) As 'Month',
      Case When p.ID = 2 Then 'Program1' When p.ID = 3 Then 'Program2'
        When p.ID = 4 Then 'Program3' End As 'Program'
    From FACT_MEMBER_MONTH_START fm
      Join DIM_COVERAGE c On fm.MEMBER_ID = c.MEMBER_ID
      Join DIM_PROGRAM p On c.PROGRAM_ID = p.ID
      Join DIM_DATE dd On fm.MONTH_ID = dd.MONTH_ID
      Join DIM_MEMBER dm On fm.MEMBER_ID = dm.ID
      Join DIM_INDIVIDUAL DI On fm.MEMBER_ID = DI.ID
      Join DIM_LIVING_SITUATION dls On fm.LIVING_SITUATION_ID = dls.ID
    Where dd.DATE Between c.EFFECTIVE_DATE And c.EXPIRATION_DATE And (dls.ID = 5
        Or dls.ID = 6) and (dd.DATE between DATEADD(MM, -18, @date) and @date)
    Group By Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' +
      Cast(DatePart(MONTH, dd.DATE) As VARCHAR) + '/01' As DATE),
      Case When p.ID = 2 Then 'FC' When p.ID = 3 Then 'PACE'
        When p.ID = 4 Then 'Part' End

UNION ALL

Select Count(Distinct fm.MEMBER_ID) As 'Count',
      Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' + Cast(DatePart(MONTH,
      dd.DATE) As VARCHAR) + '/01' As DATE) As 'Month',

      'Program4' as 'Program'  -- they are all Program4

    From FACT_MEMBER_MONTH_START fm
      Join DIM_COVERAGE c On fm.MEMBER_ID = c.MEMBER_ID
      Join DIM_PROGRAM p On c.PROGRAM_ID = p.ID
      Join DIM_DATE dd On fm.MONTH_ID = dd.MONTH_ID
      Join DIM_MEMBER dm On fm.MEMBER_ID = dm.ID
      Join DIM_INDIVIDUAL DI On fm.MEMBER_ID = DI.ID
      Join DIM_LIVING_SITUATION dls On fm.LIVING_SITUATION_ID = dls.ID
    Where dd.DATE Between c.EFFECTIVE_DATE And c.EXPIRATION_DATE And (dls.ID = 5
        Or dls.ID = 6) and (dd.DATE between DATEADD(MM, -18, @date) and @date)
    Group By Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' +
      Cast(DatePart(MONTH, dd.DATE) As VARCHAR) + '/01' As DATE)

 ORDER BY Month desc, Program

據我了解,您想要的是:

Select Count(Distinct fm.MEMBER_ID) As 'Count',
       Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' +
            Cast(DatePart(MONTH, dd.DATE) As VARCHAR) +
            '/01' As DATE) As 'Month',
       Case
         When p.ID = 2 Then 'Program1'
         When p.ID = 3 Then 'Program2'
         When p.ID = 4 Then 'Program3'
       End As 'Program'
  From FACT_MEMBER_MONTH_START fm
  Join DIM_COVERAGE c On fm.MEMBER_ID = c.MEMBER_ID
  Join DIM_PROGRAM p On c.PROGRAM_ID = p.ID
  Join DIM_DATE dd On fm.MONTH_ID = dd.MONTH_ID
  Join DIM_MEMBER dm On fm.MEMBER_ID = dm.ID
  Join DIM_INDIVIDUAL DI On fm.MEMBER_ID = DI.ID
  Join DIM_LIVING_SITUATION dls On fm.LIVING_SITUATION_ID = dls.ID
  Where dd.DATE Between c.EFFECTIVE_DATE And c.EXPIRATION_DATE And
        (dls.ID = 5 Or
         dls.ID = 6) and
        (dd.DATE between DATEADD(MM, -18, @date) and @date)
  Group By ROLLUP Cast(Cast(DatePart(YEAR, dd.DATE) As VARCHAR) + '/' +
                       Cast(DatePart(MONTH, dd.DATE) As VARCHAR) +
                       '/01' As DATE),
                  p.ID
  ORDER BY Month desc

這個查詢可以簡化一點。 有一些不需要的東西,也有一些性能瓶頸可以改善。

DECLARE @date datetime = CONVERT(date, getdate()) ;  
/* 
    NOTE: getDate() returns a datetime datatype. No need to CONVERT(). 
    But, I'm guessing this input is coming in as an application input. In 
    that case, it will probably still need the CONVERT().
*/

/* s1 CTE holds the base data for the later UNIONs. */
; WITH s1 AS ( 
    SELECT Count(Distinct fm.MEMBER_ID) AS [Count]
          /* 
            There is a lot of heavy string processing for @date that can be avoided. Also, we 
            may not need the CAST. It will return the datatype of @date 
          */
        , CAST( CONVERT(varchar,DATEADD(day,-DAY(@date)+1,@date),111) AS date) AS [Month] 
        , CASE C.PROGRAM_ID
            WHEN 2 THEN 'Program1' 
            When 3 Then 'Program2'
            When 4 Then 'Program3' 
          END AS Program
    FROM FACT_MEMBER_MONTH_START fm
        INNER JOIN DIM_COVERAGE c On fm.MEMBER_ID = c.MEMBER_ID
            AND c.PROGRAM_ID IN ( 2,3,4 ) /* Do we only care about these programs? */
          /* Join DIM_PROGRAM p On c.PROGRAM_ID = p.ID */ /* Is this table needed? */
        INNER JOIN DIM_DATE dd On fm.MONTH_ID = dd.MONTH_ID
            AND dd.DATE BETWEEN DATEADD(month, -18, @date) AND @date
            AND dd.DATE BETWEEN c.EFFECTIVE_DATE AND c.EXPIRATION_DATE
        /* DIM_DATE JOIN should be able to be much simplified. */     
        INNER JOIN DIM_MEMBER dm ON fm.MEMBER_ID = dm.ID
        INNER JOIN DIM_INDIVIDUAL DI ON fm.MEMBER_ID = DI.ID
        INNER JOIN DIM_LIVING_SITUATION dls ON fm.LIVING_SITUATION_ID = dls.ID
            AND dls.ID IN ( 5, 6 )  /* Since we were filtering with these, just use in JOIN. */
    GROUP BY 
        CONVERT(varchar,DATEADD(day,-DAY(dd.DATE)+1,dd.DATE),111) /* Simplified */
        , c.PROGRAM_ID
) 
SELECT s1.[Month]
    , s1.[Count]
    , s1.Program
FROM s1    

UNION ALL

SELECT s.[Month]
    , SUM(s.[Count]) AS [Count]
    , 'Program4' AS Program
FROM s1 s    
GROUP BY s.[Month]

ORDER BY [Month],Program

我使用通用表表達式(CTE)( s1 )來獲取本Program每月的總數,然后從CTE中SELECT該總數,這應該給我所有MonthProgram的計數明細。 然后,我SELECT從CTE,只是再次SUM()所有節目的Month ,然后UNION ALL這回第一個查詢。 這應該使我在Month Program4中有一個排位。

我不知道這是如何需要被發送到你的圖表系統,但這個查詢也可以轉化為PIVOT使每個Month僅有一行。

免責聲明:沒有數據,我無法測試,但它應該運行得更快,並且仍返回與以前相同的數據。 您可能需要調整過濾器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM