SQL Server:WHERE子句

时间:2017-08-09 11:27:12

标签: sql sql-server case where

我正在尝试合并一对几乎相同的查询,根据参数化变量(管道和完成)使用略有不同的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. 我可以使用变量在CASE语句中创建SELECT语句,还是SET根据@ApplictnDate生成CASE

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

  3. 由于

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

但请注意,在OR之前评估AND F.E. if ($user->avatar !== 'man.png' && $user->avatar !== 'woman.png') $file = public_path('uploads/avatars/' . $user->avatar); if (File::exists($file)) { unlink($file); } } 评估为a=1 OR b=1 AND c=1,而不是a=1 OR (b=1 AND c=1) 因此,请使用括号来避免AND / OR陷阱

(a=1 OR b=1) AND c=1

答案 2 :(得分:0)

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

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