一个SQL查询,它可以处理在SQL Server都为空或重视的日期范围(A single sql q

2019-08-17 07:23发布

使用SQL Server 2008中我有一个存储过程具有开始和结束日期,日期范围的输入参数。

寻找具有起点和终点之间的日期,它可以处理这两种情况下的日期或者是都为null或具有值在where子句中单个 SQL查询。

我不想使用IF语句。

Answer 1:

WITH    limits AS
        (
        SELECT  COALESCE(@startDate, MIN(mydate)) AS startDate, COALESCE(@endDate, MAX(mydate)) AS endDate
        FROM    mytable
        )
SELECT  m.*
FROM    limits
JOIN    mytable m
ON      mydate BETWEEN startDate AND endDate

如果在索引这将是最有效的mydate ,因为这种情况是优化搜索,并会使用Index Seek

如果没有索引,然后使用IFNULL由他人提出的构建。



Answer 2:

你可以这样做:

SELECT blah
FROM MyTable
WHERE 
    (@startDate IS NULL OR MyTable.StartDate >= @startDate)
    AND (@endDate IS NULL OR MyTable.EndDate <= @endDate)

但是请注意,大量的参数和子句这样可能会导致错误缓存查询计划。 有对SO有关不正确的查询计划和参数“嗅探”很多问题。



Answer 3:

Quassnoi的答案可能是最好的,但这里的另一个看法:

SELECT *
FROM MyTable
WHERE 
    MyTable.StartDate >= ISNULL(@startDate, MyTable.StartDate)
    AND MyTable.EndDate <= ISNULL(@startDate, MyTable.EndDate)


Answer 4:

SELECT *
FROM MyTable
WHERE 
     MyTable.StartDate >= COALESCE(MyTable.StartDate, "1/1/1900") 
     /* Date selected as earliest plausible constant to avoid min() lookup */

 AND MyTable.EndDate <= COALESCE(MyTable.EndDate, "1/1/3001")
     /* Date selected as latest plausible constant to avoid max() lookup */

您需要选择正确的常量为您的应用程序/域,很明显。 这是一丁点风险,如果您还没有常数足够宽,但速度快了很多比明确寻找最小值/最大值从工作台中,和大多数应用程序/域有恰当的定义框架。



Answer 5:

SELECT
    Column1,....
    FROM MyTable
    WHERE MyTable.StartDate>=COALESCE(@startDate,CONVERT(datetime,'01/01/1753'))
        AND MyTable.EndDate<=COALESCE(@endDate,CONVERT(datetime,'12/31/9999'))

另外,这里是对这个话题非常全面的文章:

在T-SQL的动态搜索条件的厄兰Sommarskog

它涵盖了所有的问题,并试图写有多个可选的搜索条件的查询方法

这里是表的内容:

   Introduction
      The Case Study: Searching Orders
      The Northgale Database
   Dynamic SQL
      Introduction
      Using sp_executesql
      Using the CLR
      Using EXEC()
      When Caching Is Not Really What You Want
   Static SQL
      Introduction
      x = @x OR @x IS NULL
      Using IF statements
      Umachandar's Bag of Tricks
      Using Temp Tables
      x = @x AND @x IS NOT NULL
      Handling Complex Conditions
   Hybrid Solutions – Using both Static and Dynamic SQL
      Using Views
      Using Inline Table Functions
   Conclusion
   Feedback and Acknowledgements
   Revision History


Answer 6:

你可以这样做

SELECT blah
FROM MyTable
WHERE 
1 = case 
        when @startDate IS NOT NULL then  MyTable.Date >= @startDate
    else 1 end
AND
1 = case 
        when @endDate IS NOT NULL then  MyTable.Date <= @endDate
    else 1 end

要么

SELECT blah
FROM MyTable
WHERE 
(
    (@startDate is not null and @endDate is not null and MyTable.Date between @startDate and @endDate )
    or
    (@startDate is null and @endDate is null )
)


Answer 7:

对于最大值:

Case when @a > @b or @b is null then @a else @b end.

这种处理空值也是如此。

简单。



文章来源: A single sql query which can handle both null or valued date range in sql server