简化SQL查询逻辑

时间:2013-09-12 17:36:15

标签: sql

我有一个在存储过程中使用的查询。我试图简化CASE语句中的逻辑。具体来说,我想将产品嵌套在UserGroup中。

SELECT DCMNumber, 
       SUM(CONVERT(INT, CurrentlyAssigned)) AS PriorAssigned
FROM dbo.cauAssignedClaim WITH(NOLOCK)
WHERE RecordType = 'A' 
  AND ([Status] <> 'DE' OR [Status] IS NULL)
  AND DATEADD(dd, 0, DATEDIFF(dd, 0, EntryDate)) 
      BETWEEN 
          CASE 
             WHEN Product IN('LTD', 'LTDCP') AND @UserGroup = '' OR @UserGroup = 'NONE'     
                 THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-30)) 
             WHEN Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup = '' OR @UserGroup = 'NONE' 
                 THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-14)) 
             WHEN Product IN('LTD', 'LTDCP') AND @UserGroup IN('SSAT', 'TCMS') 
                 THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-7)) 
             WHEN Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup IN('Appeals', 'DMS', 'Life', 'WOP', 'IWOP') 
                 THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-7)) 
          END 
      AND DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1)) 
GROUP BY [Status], DCMNumber

1 个答案:

答案 0 :(得分:1)

这来自你的原文:

BETWEEN 
      CASE 
         WHEN Product IN('LTD', 'LTDCP') AND @UserGroup = '' OR @UserGroup = 'NONE'     
             THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-30)) 
         WHEN Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup = '' OR @UserGroup = 'NONE' 
             THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-14)) 
         WHEN Product IN('LTD', 'LTDCP') AND @UserGroup IN('SSAT', 'TCMS') 
             THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-7)) 
         WHEN Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup IN('Appeals', 'DMS', 'Life', 'WOP', 'IWOP') 
             THEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-7)) 
      END 
  AND DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1)) 

可以将日期函数分解为:

BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE() - 
      CASE 
         WHEN Product IN('LTD', 'LTDCP') AND @UserGroup IN ('', 'NONE') THEN 30
         WHEN Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup IN ('', 'NONE') THEN 14
         WHEN (Product IN('LTD', 'LTDCP') AND @UserGroup IN ('SSAT', 'TCMS')) 
           OR (Product IN('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup IN('Appeals', 'DMS', 'Life', 'WOP', 'IWOP'))
           THEN 7
      END ))
  AND DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1)) 

根据Product列的可能值,您还可以执行以下操作:

  CASE WHEN Product LIKE 'LTD%' ...
       WHEN Product LIKE 'STD%' ...

最后,您错过了一个默认案例。您可以通过将ELSE子句替换为完全删除其中一个条件,我强烈建议您这样做。我怀疑最准确的默认值是30,但最大的简化可以通过默认为7:

BETWEEN DATEADD(dd, DATEDIFF(dd, 0, GETDATE() - 
      CASE 
         WHEN Product LIKE 'LTD%' AND @UserGroup IN ('', 'NONE') THEN 30
         WHEN Product IN ('STD', 'STDCP', 'SALCN', 'STAT', 'OFFOV') AND @UserGroup IN ('','NONE') THEN 14
         ELSE 7
      END ))
  AND DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1))
相关问题