2015-10-05 79 views
0

我在我們現有的一個存儲過程中找到了以下查詢。此查詢用於在兩個日期時間值之間進行記錄。在SQL Server中的兩個日期時間之間獲取記錄

SELECT office 
FROM officebudget 
WHERE officeid = @officeid 
     AND (
       (CONVERT(DATE, DateFrom) BETWEEN @wkstdate AND @wkenddate) 
       OR (CONVERT(DATE, DateTo) BETWEEN @wkstdate AND @wkenddate)); 

我有如下改寫它,

SELECT office 
FROM officebudget 
WHERE officeid = @officeid 
     AND (
       (
        bkto.DateFrom >= @wkstdate 
        AND bkto.DateFrom <= @wkenddate 
       ) 
       OR (bkto.DateTo >= @wkstdate 
       AND bkto.DateTo <= @wkenddate) 
      ); 

我得到了這兩種情況下相同的結果。但我需要知道在上述兩個查詢都會產生 不同結果的任何場景中?

(PS:DateFrom,DateTo,@Wkstdate,@Wkenddate是datetime字段)

+0

@wkstdate!='2015-09-30' –

+0

對不起,查詢可以產生不同的結果。這是一個硬編碼的價值。現在我編輯了問題 – bmsqldev

+0

'DateFrom'和'DateTo'是否有非零時間分量?如果是這樣的話,那麼您會錯過第一個查詢去除時間組件的轉換(加上第一個查詢中的轉換目前已被破壞 - 當兩個查詢中的一個甚至不能完成時詢問兩個查詢是否執行相同的操作編譯) –

回答

1

我懷疑您正在重構您的查詢以使其可用並在列DateFromDateTo上使用可能的索引。

這些將不會導致相同的結果,因爲您的查詢將忽略行的日期部分wkenddate等於datepart DateFromDateTo列值。例如,讓我們說wkenddate = '20151005'和您的列DateFrom = '20151005 15:30'。由於兩個日期部分相等,因此第一個查詢將包含此行。而您的第二個查詢將自'20151005 15:30' > '20151005'以後將省略此行。

考慮以下例子:

DECLARE @t TABLE(d DATETIME) 

INSERT INTO @t VALUES 
('20151001 10:30'), 
('20151004 10:30'), 
('20151005 10:30') 

DECLARE @wkstdate DATE = '20151001', @wkenddate DATE = '20151005' 

SELECT * FROM @t WHERE CAST(d AS DATE) BETWEEN @wkstdate AND @wkenddate 
SELECT * FROM @t WHERE d >= @wkstdate AND d <= @wkenddate 
SELECT * FROM @t WHERE d >= @wkstdate AND d < DATEADD(dd, 1, @wkenddate) 

輸出:

2015-10-01 10:30:00.000 
2015-10-04 10:30:00.000 
2015-10-05 10:30:00.000 

2015-10-01 10:30:00.000 
2015-10-04 10:30:00.000 

2015-10-01 10:30:00.000 
2015-10-04 10:30:00.000 
2015-10-05 10:30:00.000 

您應該重寫:

SELECT office 
FROM officebudget 
WHERE officeid = @officeid 
     AND (
       (
        bkto.DateFrom >= @wkstdate 
        AND bkto.DateFrom < dateadd(dd, 1 , @wkenddate) 
       ) 
       OR (bkto.DateTo >= @wkstdate 
       AND bkto.DateTo < dateadd(dd, 1, @wkenddate)) 
      ); 
+0

但是Wkenddate是用<=條件檢查的嗎?那麼它是否檢查Wkenddate的相等和更短的日期? – bmsqldev

+0

我已經詳細闡述了這個答案。 –

+0

因此,在比較之前將Datefrom和DateTo轉換爲Date是很好的做法嗎? – bmsqldev

0

不同的是,在第一個查詢,您的過濾列(FateFrom和dateTo)方法使用一個函數(CONVERT)那麼如果引擎存在,引擎就不能使用它的索引,所以第一個查詢往往會變慢。

在第二個查詢中,您手動輸入瞭如下所示的日期:2015-09-30。 最好是這樣輸入:20150930,因爲這最後的形式不依賴於服務器的區域,而第一種形式是。

+0

我的任何一種情況都是將返回不同的結果集?(PS:我已經刪除了硬編碼的值) – bmsqldev

0

在某些情況下,它會給你不同的結果,或者最糟糕的NO結果。

舊代碼有CONVERT的原因是,開發人員希望確保他比較相同的確切數據類型以避免錯誤或意外結果。請參閱下面的示例以進一步瞭解。

這一個將返回FALSE:類似給你不同的結果。

DECLARE @date1 DATETIME = GETDATE() --2015-10-05 16:15:54.780 , i used date today 
    DECLARE @date2 DATETIME = '20151005' 

    IF @date1 = @date2 
    BEGIN 
     SELECT 'TRUE' 
    END 
    ELSE 
     SELECT 'FALSE' 

而這一次將返回TRUE:像給你同樣的結果

DECLARE @date1 DATETIME = CONVERT(DATE,GETDATE()) 
    DECLARE @date2 DATETIME = CONVERT(DATE,'20151005') 

    IF @date1 = @date2 
      BEGIN 
       SELECT 'TRUE' 
      END 
      ELSE 
       SELECT 'FALSE' 

希望我的樣本可以幫助您分析您的代碼,我的建議是CONVERT它首先兩個日期比較於前你得到確切的結果。

+0

我認爲第一個查詢將返回false :)。感謝您的建議 – bmsqldev

+0

@ user5359841,正如我對我的解釋所說:) – Japongskie

相關問題