SQL搜索值之间的日期,如果为NULL,则搜索Min / Max

时间:2010-09-20 07:33:33

标签: sql sql-server tsql

我有一个T-SQL存储过程,我想搜索一个特定的值,并且可选地将搜索限制在特定日期(如果它们被传入)。如果为这些日期中的任何一个传递空值,那么我想要忽略那些。我想通过将输入日期设置为最小值或最大值(如果它们为空)来实现此目的的方式。我不想硬编码最小值和最大值。所以我想知道C#DateTime.MaxValueDateTime.MinValue的SQL等价物是什么。

我正在考虑像这样使用Coalesce

SELECT EmployeeName FROM Employee
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, <MinDateTime>) AND  
                 Coalesce(@EndDate, <MaxDateTime>)

我可以使用内置函数/常量/变量/枚举用于<MinDateTime><MaxDateTime>变量吗?

有什么建议吗?

3 个答案:

答案 0 :(得分:11)

SQL Server中没有这样的功能。您可以轻松找到BOL允许的min and max dates(1753-01-01 - 9999-12-31)。或者您可以轻松地对另一个日期进行硬编码(如果您真的正在使用生日,1800-01-01 - 2100-12-31可能就足够了)。或者你可以(如果它是你展示的范围查询),让合并回到生日本身:

SELECT EmployeeName FROM Employee
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Birthday) AND  
                 Coalesce(@EndDate, Birthday)

但请注意,对于非常大的表格,这不一定能很好地扩展。

接受后编辑,回复OP的评论

通常,对于SQL,如果您经常需要“引用”数据,请自行将其添加为表格。 (谷歌的“日历表”或“数字表sql”)。所以在这种情况下,如果你想,你可以添加一个“常量”(或者可能是“限制”表):

create table Constants (
    Lock char(1) not null,
    datetimeMin datetime not null,
    datetimeMax datetime not null,
    intMin int not null,
    intMax int not null,
    /* Other Min/Max columns, as required */
    constraint PK_Constants PRIMARY KEY (Lock),
    constraint CK_Constants_Locked CHECK (Lock='X')
)
insert into Constants (Lock,datetimeMin,datetimeMax,intMin,intMax)
select 'X','17530101','99991231',-2147483648,2147483647

然后您可以在查询中引用(通过子选择,或通过交叉连接到此表)。 E.g。

SELECT EmployeeName
FROM Employee, Constants
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN Coalesce(@StartDate, Constants.datetimeMin) AND  
                 Coalesce(@EndDate, Constants.datetimeMax)

(Lock,Primary Key和Check约束,协同工作以确保此表中只存在一行)

答案 1 :(得分:4)

对于SQL Server,根据BOL,限制为:

  • datetime:1753-01-01 00:00:00至9999-12-31 23:59:59.997
  • smalldatetime:1900-01-01 00:00:00至2079-06-06 23:59:29.998
  • date:0001-01-01至9999-12-31
  • datetime2:0001-01-01 00:00:00至9999-12-31 23:59:59.9999999

如您所见,这取决于您的确切数据类型。

至于查询,我会这样做:

SELECT EmployeeName
FROM Employee
WHERE  EmployeeID = @EmployeeId
 AND  (@StartDate IS NULL
  OR   Birthday >= @StartDate)
 AND  (@EndDate   IS NULL
  OR   Birthday <= @EndDate)

答案 2 :(得分:3)

没有内置函数来获取最小或最大日期时间值。您必须对值进行硬编码或从数据库中检索值。

如果参数为NULL,您只需选择最小值和最小值即可。最大日期来自Employee表格。

IF (@StartDate IS Null)
BEGIN
 SELECT @StartDate = MIN(Birthday) FROM Employee
END


IF (@EndDate IS Null)
BEGIN
 SELECT @EndDate = MAX(Birthday) FROM Employee
END

SELECT EmployeeName FROM Employee
WHERE  EmployeeID = @EmployeeId AND
Birthday BETWEEN @StartDate AND  @EndDate