【问题标题】:SQL Server : DATE or NULL Variable in WHERE clauseSQL Server:WHERE 子句中的 DATE 或 NULL 变量
【发布时间】:2017-08-09 11:27:12
【问题描述】:

我正在尝试合并一对几乎相同的查询,这些查询使用略有不同的WHERE 子句,具体取决于参数化变量(管道和完成)。

我正在努力找出最好的编码方式,以根据@ReportMode 变量查找日期范围或NULL。

第一个实例中的WHERE 子句本质上是:

DECLARE @ReportMode VARCHAR(20),
        @ApplictnDate DATETIME;

SET @ApplictnDate = 
    CASE 
       WHEN @ReportMode = 'Completions' THEN '20160801 00:00:00'
       WHEN @ReportMode = 'Pipeline'    THEN '20170201 00:00:00'
    END        

SELECT 
    Id, AppDate, CompDate 
FROM 
    TbTable 
WHERE 
    AppDate > @ApplictnDate AND
    CompDate BETWEEN '20170701 00:00:00' AND '20170731 00:00:00'

第二个查询是:

DECLARE @ReportMode VARCHAR(20),
        @ApplictnDate DATETIME;

SET @ApplictnDate = 
    CASE 
       WHEN @ReportMode = 'Completions' THEN '20160801 00:00:00'
       WHEN @ReportMode = 'Pipeline'    THEN '20170201 00:00:00'
    END        

SELECT 
    Id, AppDate, CompDate 
FROM 
    TbTable 
WHERE 
    AppDate > @ApplictnDate AND
    CompDate IS NULL

问题

  1. 我可以使用变量在SELECT 语句中创建CASE 语句,还是需要根据@ApplictnDate 设置为SET

  2. 如何在语法上创建 CASE 语句来处理 NULL 或日期范围?

谢谢

【问题讨论】:

  • 只需使用 OR 和 () 将 where 语句保持为一个单元?
  • 只是吹毛求疵:CASE 是 T-SQL 中的 表达式(如 a+b) - 不是语句。它是被评估为单个原子值的东西。

标签: sql sql-server case where


【解决方案1】:

如果您最近没有阅读或重新阅读Sommaskogs blog post,那么绝对值得一读,以避免最典型的性能问题。

【讨论】:

    【解决方案2】:

    我建议不要使用单个查询。这是可能的,但查询处理器将缓存它遇到的第一个版本,但对于每个空值和非空值可能会有更好的计划。因此,您可能会遇到性能问题。

    更好的方法是针对每个案例单独查询或处理。如果您(非常正确地)试图避免重复,则将谓词和无参数查询作为一个视图,然后使用不同的WHERE 子句和参数应用程序分离过程/查询。

    【讨论】:

      【解决方案3】:

      CompDate 不需要 CASE,您可以使用 OR。

      但请注意,AND 在 OR 之前进行评估。
      F.e. a=1 OR b=1 AND c=1 评估为 a=1 OR (b=1 AND c=1),而不是 (a=1 OR b=1) AND c=1
      因此,请包含括号以避免 AND/OR 陷阱。

      DECLARE @ApplictnDate DATETIME = 
          CASE @ReportMode 
          WHEN 'Completions' THEN '2016-08-01' 
          WHEN 'Pipeline' THEN '2017-02-01' 
          END;
      
      DECLARE @CompDateStart DATETIME = '2017-07-01';
      DECLARE @CompDateEnd DATETIME = EOMONTH(@CompDateStart);
      
      SELECT Id,
             AppDate,
             CompDate 
      FROM TbTable 
      WHERE AppDate > @ApplictnDate
       AND (CompDate IS NULL OR CompDate BETWEEN @CompDateStart AND @CompDateEnd);
      

      【讨论】:

        猜你喜欢
        • 2017-06-16
        • 2013-06-14
        • 2019-01-05
        • 1970-01-01
        • 2013-06-25
        • 2017-10-09
        • 1970-01-01
        • 1970-01-01
        • 2017-07-20
        相关资源
        最近更新 更多