使用SQL Server 2008.我有一个存储过程,它有开始日期和结束日期作为日期范围的输入参数。
在where子句中查找单个 sql查询,该查询的开始日期和结束日期之间可以处理日期为空或两者都有值的两种情况。
我不想使用IF语句。
答案 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.
这也处理空值。
简单。