如何在SELECT和WHERE子句中使用CASE来消除除零问题

时间:2015-03-26 02:55:39

标签: sql sql-server tsql sql-server-2008-r2

使用SQL Server 2008 R2,我有一个查询现在给我一个除零错误。这是因为DB列值总是应该>这已经改变了。该列为wf.reminderFrequency,现在设置为无空值,默认值为0.

以下是查询:

SELECT 
    wfi.WebFormsInstanceID AS instanceID, 
    wfi.FormActionDate as fLastActionDate, 
    wf.reminderFrequency as fReminderFeq, 
    DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
    CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
    DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
    CAST(GETDATE() AS DATE)) % wf.reminderFrequency AS theModCalc 
FROM 
    (webFormsInstances as wfi 
LEFT OUTER JOIN 
    WebFormsIndex as wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID) 
WHERE 
    (wfi.formStage <> 'Complete' 
     AND wfi.FormStage <> 'Terminated' 
     AND wfi.FormStage <> 'Payroll Processing') 
    AND (wfi.FormActionDate > 20150101) 
    AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency = 0) 
ORDER BY 
    wfi.WebFormsInstanceID DESC;

该查询旨在获取所有WebFormsIndex记录,其中X(wf.reminderFrequency)天数内没有发生任何操作(今天和fLastActionDate之间的差异)。请注意 - 查询比它需要的更令人困惑,因为fLastActionDate是一个YYYYMMDD整数值,遗憾的是无法更改。那么我该如何更改它来处理wf.reminderFrequency现在可以为0的场景。正如您所看到的,该值在查询的两个分区中使用。

这是我对SELECT部分​​的解决方案,我认为它将起作用:

SELECT 
    wfi.WebFormsInstanceID AS instanceID, 
    wfi.WebFormsIndexID as fID, 
    wf.FormName as fName, 
    wfi.FormOwner as fOwner, 
    wfi.FormStage as fStage, 
    wfi.FormAction as fAction, 
    wfi.FormActionDate as fLastActionDate, 
    wf.reminderFrequency, 
    wfi.Comments as fComments, 
    DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
    CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
    CASE
       WHEN wf.reminderFrequency > 0 
         THEN
           DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency 
         ELSE
            '-1'
    END AS theModCalc
FROM 
    (webFormsInstances as wfi     

但我没有运气弄清楚如何处理WHERE条款中的除法。

这不起作用:

WHERE 
    (wfi.formStage <> 'Complete' 
     AND wfi.FormStage <> 'Terminated' 
     AND wfi.FormStage <> 'Payroll Processing') 
    AND (wfi.FormActionDate > 20150101) 
    CASE
       WHEN wf.reminderFrequency > 0 
         THEN
               AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency = 0) 
        END AS          
ORDER BY 
    wfi.WebFormsInstanceID DESC;

更新 - 来自第一个语句的示例数据:

  instanceID  fLastActionDate  fReminderReq  theDateDiffCalc  theModCalc
  24965         20150312          14             14              0
  24965         20150312          14             14              0
  24940         20150226          14             28              0

感谢@Gordon使用nullif是解决方案。似乎工作得很好。在select:

中使用它是这样的
 DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % nullif(wf.reminderFrequency,0) AS theModCalc 

和WHERE中一样:

AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % nullif(wf.reminderFrequency,0) = 0) 

1 个答案:

答案 0 :(得分:3)

如果您可以将NULL作为值而不是-1处理,我建议NULLIF()

DATEDIFF(day,
         CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
         CAST(GETDATE() AS DATE)
        ) % nullif(wf.reminderFrequency, 0) AS theModCalc 

这适用于selectwhere