简体   繁体   English

在日期的Where子句中使用案例

[英]Using Case in a Where Clause for Dates

I currently have this WHERE clause that includes the following parameters. 我目前有这个WHERE子句,其中包含以下参数。

WHERE 
    Project ID=110
    AND ((CAST(saa.Date AS DATE) >= '09/24/2014' AND CAST(saa.Date AS DATE) <= '09/24/2014') OR saa.Date IS NULL))

The tricky part here is that the saa.Date is NULL section is going to pull up ALL Null Values in all dates (which is excessive) I only want to use the following Date Range for the Null Values 这里最棘手的部分是saa.Date is NULL部分将提取所有日期中的所有Null值(这是多余的),我只想使用以下Date Range作为Null

(
        (CAST(sa.StartDateTime AS DATE) >= '09/24/2014' AND CAST(sa.StartDateTime AS DATE) <= '09/24/2014')
        OR
        (CAST(sa.EndDateTime AS DATE) >= '09/24/2014' AND CAST(sa.EndDateTime AS DATE) <= '09/24/2014')
)

So I'm trying to figure out how I can create a CASE statement that would work that would be something like IF saa.Date is NULL Then [Use Date Range Parameters above] 所以我试图弄清楚如何创建一个可以正常工作的CASE语句,就像IF saa.Date为NULL然后[使用上面的日期范围参数]

I'll base my answer in @AHiggins's but adding performance an readability 我将以@AHiggins为答案,但会提高性能和可读性

-- sergability -可贴性

-- avoiding cast -避免cast

-- using between - 使用between

WHERE 
    ProjectID=110 AND 
     (
      (
        saa.Date between '09/24/2014 00:00:00.000' AND '09/24/2014 23:59:59.999'
      ) OR 
      (
        saa.Date IS NULL AND
         (
            sa.StartDateTime between '09/24/2014 00:00:00.000' AND  '09/24/2014 23:59:59.999'
         ) OR
         (
            sa.EndDateTime between  '09/24/2014 00:00:00.000' AND '09/24/2014 23:59:59.999'
         )
      )
     )     

Make sure you have indexes on thos date columns 确保您在日期列上有索引

If I'm reading it right, you should be able to do this with Boolean logic and a few million parentheses: 如果我没看错,您应该能够使用布尔逻辑和几百万个括号来做到这一点:

EDIT: noticed in the comments on @horaciux's answer that there's an issue, realized we actually need a couple more parentheses. 编辑:在@horaciux的答案的评论中注意到有一个问题,意识到我们实际上还需要几个括号。 I've borrowed back the borrowed code and added the extras below. 我已经借回了代码,并在下面添加了其他功能。

WHERE 
    ProjectID=110 AND 
     (
      (
        saa.Date between '09/24/2014 00:00:00.000' AND '09/24/2014 23:59:59.999'
      ) OR 
      (
        saa.Date IS NULL AND
         ( -- need to wrap the next two conditions in a single set of parentheses
          (
            sa.StartDateTime between '09/24/2014 00:00:00.000' AND  '09/24/2014 23:59:59.999'
          ) OR
          (
            sa.EndDateTime between  '09/24/2014 00:00:00.000' AND '09/24/2014 23:59:59.999'
          )
         )
      )
     ) 

You do know that 你知道

    >= '09/24/2014' 
AND <= '09/24/2014' 

is the same as = '09/24/2014' 与= '09 / 24/2014'相同

where ProjectID=110 
  AND CAST(saa.Date AS DATE) = '09/24/2014' 
   OR (
        saa.Date IS NULL 
        AND
            ( 
              CAST(sa.StartDateTime AS DATE) = '09/24/2014'
              OR
              CAST(sa.EndDateTime AS DATE)   = '09/24/2014' 
            )              
      )

This is more efficient than a cast: 这比强制转换更有效:

DATEADD(dd, DATEDIFF(dd, 0, COL),0)  

But the answer from Horaciux is even more efficient 但是Horaciux的答案更加有效

Try this 尝试这个

(
        (CAST(ISNULL(sa.StartDateTime, '09/24/2014') AS DATE) >= '09/24/2014' AND CAST(ISNULL(saa.StartDateTime, '09/24/2014') AS DATE) <= '09/24/2014')
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM