SQL Server:WHERE 子句中的 DATE 或 NULL 变量



我正在尝试合并一对几乎相同的查询,这些查询根据参数化变量(管道和完成(使用略有不同的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语句,还是需要根据@ApplictnDateSET它?

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

谢谢

如果您最近没有阅读或重读 Sommaskogs 博客文章,那么为了避免最典型的性能问题,它肯定值得一读。

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

更好的方法是对每种情况分别进行查询或程序。如果您(非常正确地(试图避免重复,请将谓词和无参数查询作为视图,然后使用不同的WHERE子句和参数应用来分隔过程/查询。

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

最新更新