SQL Server 2008 R2中的日期比较结果不正确

时间:2012-03-01 21:06:21

标签: linq-to-sql datetime sql-server-2008-r2

我有一个LINQ 2 SQL查询,它为我提供了2012年2月份的结果列表。结果where子句是

DECLARE @p0 DateTime = '2012-02-01 00:00:00.000'
DECLARE @p1 DateTime = '2012-02-29 23:59:59.999'
....
WHERE (CONVERT(DATE, [t0].[DatePlaced]) >= @p0) AND (CONVERT(DATE, [t0].[DatePlaced]) <= @p1)

运行时,我会看到3月1日的结果以及2/2012的所有结果。

如果我更改where子句以使用BETWEEN,那么结果只包含二月的日期。

WHERE [t0].[DatePlaced] BETWEEN @p0 AND @p1

我正在使用带有和不带SP1的.net 4和SQL Server 2008 R2。

将日期切换为3/1/2011,我的查询结束日期为'2011-02-28 23:59:59.999',结果相同。

除了使用LINQ 2 SQL不支持的BETWEEN之外,还有另一种方法可以获得2/2012的结果吗?

3 个答案:

答案 0 :(得分:4)

.999轮到第二天的午夜。你可以查看:

DECLARE @p1 DateTime = '2012-02-29 23:59:59.999';
SELECT @p1;

你得到了什么?

而不是试图弄清楚今天的最后一刻(根据数据类型和精度会有所不同),而是你想要的是一个开放式的日期范围:

DECLARE @p0 DATE = '2012-02-01',
        @p1 DATE = '2012-03-01';
....
WHERE [t0].[DatePlaced] >= @p0
AND [t0].[DatePlaced] < @p1

更简单的方法就是传递开始日期并说:

DECLARE @p0 DATE = '2012-02-01';

....
WHERE [t0].DatePlaced >= @p0
AND [t0].DatePlaced < DATEADD(MONTH, 1, @p0)

关于日期时间最佳实践的一些详细想法:

有关为什么BETWEEN(以及>= AND <=}是邪恶的一些信息:

答案 1 :(得分:3)

如果您需要经常按月选择,可以考虑在表中添加两个计算列 - 一个用于月份,一个用于年份:

ALTER TABLE dbo.YourTable
ADD DatePlacedYear AS YEAR(DatePlaced) PERSISTED

ALTER TABLE dbo.YourTable
ADD DatePlacedMonth AS MONTH(DatePlaced) PERSISTED

这两个新列是由SQL Server自动计算的,它们是持久存储的(例如表的存储的一部分),如果对你有用,你甚至可以在它们上面放一个索引。

有了这些,您现在可以使用如下查询:

SELECT (columns)
FROM dbo.YourTable
WHERE DatePlacedYear = 2012 AND DatePlacedMonth = 2

从2012年2月获取所有数据。

这是一个经典的空间 - 速度权衡 - 通过为每一行存储两个额外的列,您需要更多的空间 - 但作为回报,查询变得更容易,如果您在(DatePlacedYear, DatePlacedMonth)上有索引,你的查询应该(理想情况下)非常快。

答案 2 :(得分:0)

请尝试使用AddMilliseconds(-1)

,而不是使用AddMilliseconds(-3)

请参阅this question SQL Server如何处理毫秒数