使用SQL Server 2008中我有一个存储过程具有开始和结束日期,日期范围的输入参数。
寻找具有起点和终点之间的日期,它可以处理这两种情况下的日期或者是都为null或具有值在where子句中单个 SQL查询。
我不想使用IF语句。
使用SQL Server 2008中我有一个存储过程具有开始和结束日期,日期范围的输入参数。
寻找具有起点和终点之间的日期,它可以处理这两种情况下的日期或者是都为null或具有值在where子句中单个 SQL查询。
我不想使用IF语句。
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
由他人提出的构建。
你可以这样做:
SELECT blah
FROM MyTable
WHERE
(@startDate IS NULL OR MyTable.StartDate >= @startDate)
AND (@endDate IS NULL OR MyTable.EndDate <= @endDate)
但是请注意,大量的参数和子句这样可能会导致错误缓存查询计划。 有对SO有关不正确的查询计划和参数“嗅探”很多问题。
Quassnoi的答案可能是最好的,但这里的另一个看法:
SELECT *
FROM MyTable
WHERE
MyTable.StartDate >= ISNULL(@startDate, MyTable.StartDate)
AND MyTable.EndDate <= ISNULL(@startDate, MyTable.EndDate)
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 */
您需要选择正确的常量为您的应用程序/域,很明显。 这是一丁点风险,如果您还没有常数足够宽,但速度快了很多比明确寻找最小值/最大值从工作台中,和大多数应用程序/域有恰当的定义框架。
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
你可以这样做
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 )
)
对于最大值:
Case when @a > @b or @b is null then @a else @b end.
这种处理空值也是如此。
简单。