2017-08-02 190 views
2

以下是我目前的SQL Server 2012查询。基本上我想要从最后一个工作日获得的信息,但是在星期一,我希望它能够取消周五的信息,而不是周日。这是我在查询中迄今为止的内容,但它不会接受它。CASE在WHERE子句

USE [LetterGeneration] 

SELECT 
    g.LetterGenerationPrintJobId, 
    CONVERT(CHAR(12), r.CreatedDate, 101) AS CreatedDate, 
    YEAR(r.CreatedDate) AS Year, 
    MONTH(r.CreatedDate) AS Month, 
    DAY(r.CreatedDate) AS Day, 
    CASE 
     WHEN DATEPART(dw, r.CreatedDate) = 1 
      THEN 1 
     WHEN DATEPART(dw, r.CreatedDate) = 7 
      THEN 1 
     ElSE 0 
    END AS Weekend, 
    s.LetterGenerationStatusId AS Status, 
    COUNT(g.LetterGenerationId) AS LetterCount, 
    SUM(g.LetterPageCount) AS PageCount, 
    t.IsLitigationCoverLetterAllowed, 
    CASE 
     WHEN g.CarrierTrackingNumber LIKE '%1ZE%' 
      THEN 1 
     WHEN g.CarrierTrackingNumber LIKE '921489%' 
      THEN 2 
     WHEN g.CarrierTrackingNumber LIKE '917190%' 
      THEN 2 
     ELSE 3 
    END AS CarrierType 
FROM 
    [LetterGenerationTemplateRequest] AS R 
INNER JOIN 
    [LetterGenerationTemplate] AS T ON t.[LetterGenerationTemplateId] = r.LetterGenerationTemplateId 
INNER JOIN 
    LetterGeneration G ON g.LetterGenerationTemplateRequestId = r.LetterGenerationTemplateRequestId 
INNER JOIN 
    LetterGenerationStatus S ON g.LetterGenerationStatusId = s.LetterGenerationStatusId 
WHERE 
    (CASE 
     WHEN (DATENAME(dw,GETDATE()) = 'Monday') 
      THEN (DATEDIFF(d, r.CreatedDate, GETDATE()) = 3) 
     ELSE (DATEDIFF(d, r.CreatedDate, GETDATE()) = 1) 
    END) 
    AND t.[TemplateKey] NOT LIKE '%PLTV1%' 
    AND s.LetterGenerationStatusId = 19 
ORDER BY 
    r.CreatedDate DESC, g.LetterGenerationPrintJobId DESC 

我对我的WHERE子句有什么想法或误解,以便让它以我想的方式工作?

谢谢

回答

1

我缺少什么,或者为了让它在我想的方式工作,误解我的WHERE子句?

虽然你没有给你得到错误信息,我敢肯定,这句法相关的,因为你把测试内部的情况的结果,而不是外面

你”重新书写:

WHERE CASE WHEN it_is_monday THEN data_date = friday ELSE data_date = yesterday END 

你应该写:

WHERE data_date = CASE WHEN it_is_monday THEN friday ELSE yesterday END 

本质:你不应该在一个地方时使用情况/子句做你的“列=东西”的比较,并返回你真或假,你应该用它来返回你比较的“东西”与其他列“其他”以获得你的真实或假的

其他答案的重点是“给你一个工作解决方案”;这个答案集中在告诉你什么是与你的思维过程脚麻重新原始查询

这里有一个简单的例子:

--wrong syntax to search a table full of cats (4 legs) and people (2 legs) 
WHERE CASE WHEN animal_type = 'cat' THEN legs = 4 ELSE legs = 2 END 

--right syntax 
WHERE limbs = CASE WHEN animal_type = 'cat' THEN 4 ELSE 2 END 
+0

这是一个非常好的解释。我明白现在我的病例陈述中哪里出了问题。现在看起来像这样: WHERE DATEDIFF(d,r。CreatedDate,GETDATE())=(CASE \t \t \t \t \t \t \t \t \t \t \t \t WHEN DATENAME(DW,GETDATE())= '星期一' THEN 3 \t \t \t \t \t \t \t \t \t \t \t \t ELSE 1 \t \t \t \t \t \t \t \t \t \t \t \t END) –

4

也许转换为常规AND/OR?

WHERE (
    ((DATENAME(dw,GETDATE()) = 'Monday') AND (DATEDIFF(d, r.CreatedDate, GETDATE()) = 3)) 
    OR 
    (DATEDIFF(d, r.CreatedDate, GETDATE()) = 1) 
) 
.... 
+0

似乎工作得很好。感谢您的聪明,简单的解决方案。 –

0

忽略假期第二,假设你至少有一个记录每日期,这样的事情应该工作。

0

为了保持SARGability(能够做一个寻求对索引)你想确保谓词的表列中不包含任何功能。

以下应该工作,并保持SARGability ...

WHERE 
    r.CreatedDate = CASE 
         WHEN DATEPART(dw, getdate) = 2 
         THEN DATEADD(dd, -3, CAST(GETDATE() AS DATE)) 
         ELSE CAST(GETDATE() AS DATE) 
        END 

HTH, 杰森