如何编写两个case语句以防万一

时间:2016-07-05 07:42:36

标签: sql-server

我的查询显示错误,任何人都可以帮助我。

我的查询:

SELECT     A.EmpCodeC, 
           E.EmpNameC, 
           B.DesigNameC, 
           C.DeptNameC, 
           D.SecNameC, 
           A.ClockDateD, 
           TimeClk1N, 
           TimeClk2N, 
           TimeClk3N, 
           TimeClk4N, 
           A.BJClk1N, 
           A.BJClk2N, 
           A.BJClk3N, 
           A.BJClk4N, 
           A.TimeInN, 
           A.TimeOutN, 
           A.ShiftCodeC, 
           A.NormalN, 
           A.ActlWrkHrsN, 
           A.LatenessN, 
           A.UnderN, 
           A.OT10N, 
           A.OT15N, 
           A.OT20N, 
           A.OT30N, 
           A.SflatN, 
           A.ShiftAllN, 
           A.MealAllN, 
           A.TranAllN, 
           A.Oth1AllN, 
           A.Oth2AllN, 
           A.HealthAllN, 
           A.AttdAllN, 
           A.ReaCodeC, 
           A.SplReaCodeC, 
           Isnull(I.PayTypeC, '') PayType, 
           E.BasicSalaryN, 
           CASE 
                      WHEN Datename(dw, A.ClockDateD)='Sunday' THEN 
                                 CASE 
                                            WHEN A.OT20N >4 THEN ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (4+A.OT10N+A.OT20N+ A.OT30N))
                                            ELSE ((E.BasicSalaryN                /(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2) )/9)* (A.OT10N+A.OT15N+ A.OT20N+ A.OT30N))
                                 END AS OT_Amnt, 
                                 CASE 
                                            WHEN A.OT20N >4 THEN ((E.BasicSalaryN/(SubString(CAST(EOMONTH ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (A.OT15N-4)) 
                                            ELSE ('0.00') 
                                 END AS Insentive_Amnt 
                      ELSE '0.00' OT_Amnt '0.00' Insentive_Amnt 
           END 
FROM       Daily A 
INNER JOIN TMSStrt.DBO.Designation B 
ON         A.DesigCodeC = B.DesigCodeC 
INNER JOIN TMSStrt.DBO.Department C 
ON         A.DeptCodeC = C.DeptCodeC 
INNER JOIN TMSStrt.DBO.Section D 
ON         A.SecCodeC = D.SecCodeC 
AND        D.DeptCodeC = C.DeptCodeC 
INNER JOIN StaffMaster E 
ON         A.EmpCodeC = E.EmpCodeC 
LEFT JOIN  TMSStrt.DBO.Reason I 
ON         A.ReaCodeC = I.ReasonCodeC 
WHERE      A.ClockDateD >= '01-07-2016' 
AND        A.ClockDateD <= '04-07-2016' 
ORDER BY   E.EmpNameC, 
           A.ClockDateD

2 个答案:

答案 0 :(得分:0)

您的外部CASE错了。哟不能从CASE里面返回两列,你只能返回一个值。所以你可以这样写:

       ...
       CASE 
           WHEN Datename(dw, A.ClockDateD)='Sunday' THEN 
               CASE 
                   WHEN A.OT20N >4 THEN ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (4+A.OT10N+A.OT20N+ A.OT30N))
                   ELSE ((E.BasicSalaryN                /(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2) )/9)* (A.OT10N+A.OT15N+ A.OT20N+ A.OT30N))
               END 
           ELSE 0.0 
       END AS OT_Amnt,
       CASE 
           WHEN Datename(dw, A.ClockDateD)='Sunday' AND A.OT20N >4 THEN ((E.BasicSalaryN/(SubString(CAST(EOMONTH ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (A.OT15N-4)) 
           ELSE 0.0
       END AS Insentive_Amnt,
       ...

还要注意varchar CAST,SUBSTRING以及算术中混合数字和sting数据的日期。最好使用日期函数(例如:Year(EOMONTH ( A.ClockDateD ))-2000而不是(SubString(CAST(EOMONTH ( A.ClockDateD ) AS VARCHAR(20)),9,2)

答案 1 :(得分:0)

好的,看看你到目前为止的情况 - 你的查询有点错误。 首先,你嵌套的case语句(这不会顺便说一下)有完全相同的行为吗?我认为他们应该如下

个案陈述:

      CASE 
        WHEN Datename(dw, A.ClockDateD)='Sunday' AND A.OT20N >4 
        THEN ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (4+A.OT10N+A.OT20N+ A.OT30N))
        ELSE ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2) )/9)* (A.OT10N+A.OT15N+ A.OT20N+ A.OT30N))
      END AS OT_Amnt


     CASE 
       WHEN Datename(dw, A.ClockDateD)='Sunday' WHEN A.OT20N >4 
       THEN ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2))/9)* (4+A.OT10N+A.OT20N+ A.OT30N))
       ELSE ((E.BasicSalaryN/(Substring(Cast(Eomonth ( A.ClockDateD ) AS VARCHAR(20)),9,2) )/9)* (A.OT10N+A.OT15N+ A.OT20N+ A.OT30N))
     END AS Insentive_Amnt,

完全删除了嵌套,只需调用两个单独的case语句,MSSQL在复制case语句时有可忽略的开销。

如果您想保留您的嵌套构思,则需要切换到存储过程。在那里,您可以使用if语句设置变量,然后在if语句中调用case语句。

从我看到的情况来看,你不需要存储过程。另一个说明

ELSE '0.00' OT_Amnt '0.00' Insentive_Amnt

我不知道这是什么,但是如果你想要连接一些你需要使用&amp;的东西,那么永远不会工作或+语法取决于数据类型。