2012-03-01 131 views
0

我的影片讓我結果的列表爲2012年2月得到的where子句的一個月LINQ 2 SQL查詢不正確的日期比較結果在SQL Server 2008 R2

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) 

在運行此我」獲得2012年3月1日的結果以及2012年2月的所有結果。

如果我將where子句更改爲使用BETWEEN,那麼結果僅包含2月份的日期。

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

我正在使用.net 4和SQL Server 2008 R2(帶和不帶SP1)。

將日期切換到2011年3月1日,我的查詢結束日期爲'2011-02-28 23:59:59.999'的結果相同。

除了使用LINQ 2 SQL不支持的BETWEEN之外,是否還有另一種獲得僅用於2/2012的結果的方法?

回答

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) 

有關日期時間精心製作的一些想法最佳實踐:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx

有關爲什麼BETWEEN(通過擴展>= AND <=)是邪惡的一些信息:

http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx

而且蒂博爾出​​色的日期/時間資源:

http://www.karaszi.com/SQLServer/info_datetime.asp

3

如果您需要按月往往選擇,你可以考慮將兩個計算列的表 - 一個是一個月,一個年度:

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

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

這兩個新列由SQL自動計算服務器,它們是持久的(例如表的存儲的一部分),甚至可以在它們上面放置索引,如果這對你有意義的話。

與那些在地方,你現在可以使用這樣的查詢:

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

從2012年2月獲得的所有數據

這是一個經典的空間VS-速度的權衡 - 通過存儲每行需要兩個額外的列,你需要更多的空間 - 但作爲迴應,查詢變得更容易,如果你有一個索引(DatePlacedYear, DatePlacedMonth),你的查詢應該(相當快)。

+0

而不是添加計算列,我只是簡單地比較日期的月份和年份部分。我相信這是一種性能上的折衷,但它只是用於內部報告,所以目前這不是什麼大問題。 – 2012-03-11 04:47:24

0

而不是使用AddMilliseconds(-1)試使用AddMilliseconds(-3)

請參閱this question SQL Server如何處理毫秒

+2

依靠毫秒是有問題的。如果底層數據類型轉換爲SMALLDATETIME會怎麼樣?現在你的結果又回來了。如果它轉換爲DATETIME2(> 2)會怎樣?現在,你的範圍的結束實際上是在一天結束之前,你理論上可能會錯過數據。一個開放式的日期範圍實際上是獲得一整天數據的唯一面向未來的方法。 – 2012-03-02 00:14:33