单个sql查询,可以处理sql server中的null或value日期范围

时间:2009-10-05 15:22:52

标签: sql sql-server tsql sql-server-2008

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

在where子句中查找单个 sql查询,该查询的开始日期和结束日期之间可以处理日期为空或两者都有值的两种情况。

我不想使用IF语句。

7 个答案:

答案 0 :(得分:12)

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构造。

答案 1 :(得分:10)

你可以这样做:

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

但请注意,像这样的AND子句中的大量参数可能会导致错误地缓存查询计划。关于错误的查询计划和参数'嗅探',有很多问题。

答案 2 :(得分:4)

Quassnoi的回答可能是最好的,但这是另一回事:

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

答案 3 :(得分:2)

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 */

显然,您需要为您的应用/域选择正确的常量。如果你没有足够宽的常数但比从表中明确地查看最小值/最大值要快得多,并且大多数应用程序/域具有非常好定义的帧,那么这有点冒险。

答案 4 :(得分:1)

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

另外,这是一篇关于这个主题的非常全面的文章:

Dynamic Search Conditions in T-SQL by Erland 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

答案 5 :(得分:1)

你可以这样做

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

答案 6 :(得分:0)

最大值:

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

这也处理空值。

简单。