案例在WHERE条款中

时间:2017-08-02 16:21:24

标签: sql sql-server case

以下是我当前的SQL Server 2012查询。基本上我想要上一个工作日的信息,但是在星期一,我希望它能够提取星期五的信息,而不是周日。这是我目前在查询中所拥有的内容,但它不会接受它。

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条款有什么遗漏或误解,以使其按照我的思维方式运作?

由于

4 个答案:

答案 0 :(得分:4)

也许转换为常规的AND / OR?

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

答案 1 :(得分:1)

  

为了让它以我正在思考的方式运作,我对WHERE子句有什么遗漏或误解?

虽然你没有给出错误消息,但我确定它的语法相关,因为你把测试INSIDE放在案例的结果中,而不是在它之外

你在写:

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

基本上:你不应该使用case /在where子句中进行你的“column = something”比较并返回true或false,你应该用它来返回你的“某事”与“列”比较,以获得你的真或假

其他答案的重点是“为您提供有效的解决方案”;这个答案的重点是告诉你原始查询的思考过程出了什么问题

这是一个更简单的例子:

--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

答案 2 :(得分:0)

忽略假期一秒钟,并假设每个日期至少有一条记录,这样的事情应该有效。

where cast(createdDate as date) = 
(select max(createdDate )
from table
where createdDate < cast(getDate() as date
and dateName(dw, createdDate in ('Monday' etc)
)

答案 3 :(得分: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, 杰森