2016-08-25 119 views
1

我在yyyymmdd日期有一個痛苦的時間。在此DB中,null日期存儲爲空字符串。對於SQL Server日期不能使用BETWEEN

此執行就好了,我可以手動檢查有在日期

SELECT 
    effective, expiration 
FROM 
    (SELECT 
     CONVERT(date, date_effective, 112) as effective, 
     CONVERT(date, date_expiration, 112) as expiration 
    FROM ...) AS X 

但後來沒有不良時,我希望他們像這樣比較:

... 
) AS X 
WHERE 
    GETDATE() BETWEEN effective AND expiration 

,這將引發一個錯誤

從字符串轉換日期和/或時間時轉換失敗。

我溺水並花了數小時試圖讓這個日期轉換工作。我擔心我唯一的選擇是將我想要的東西粘到臨時表中。日期轉換不應該很難。請幫助我轉換這些日期,並能夠比較它們。

編輯:有這非常大的數據庫DIRTY行,中行的0.003%是壞的

+0

你能否確認你沒有任何「髒」行,即那些不適合yyyymmdd或空字符串模式的行? – SqlOnly

+0

我不能,我懷疑是這樣。我要去處理一下 –

+0

@SqlOnly BINGO有髒數據,我該如何處理? –

回答

1

不知道你的約會對象的確切數據類型字符串(varchar,nvarchar,長度等),很難規定完美的解決方案。你的問題(和可能的解決方案)也與SO 4384709非常相似。鑑於這些警告,我會追求臨時表解決方案(請參閱「@tblCleanDatesAndThings」),如下所示。

--Define a table structure for debugging 
DECLARE @tblDatesAndThings TABLE 
    (
    date_effective varchar(100) NULL 
    ,date_expiration varchar(100) NULL 
    ) 

--Insert some test data 
INSERT INTO @tblDatesAndThings 
    SELECT '','' --Bad data (per original question) 
    UNION SELECT CONVERT(VARCHAR(100), DATEADD(d, -1, GETDATE())), CONVERT(varchar(100), DATEADD(d,1, GETDATE())) 
    UNION SELECT CONVERT(VARCHAR(100), DATEADD(d, -2, GETDATE())), CONVERT(VARCHAR(100), DATEADD(d, 2, GETDATE())) 
    UNION SELECT 'a', 'b' --Bad data (per later edit/comment) 

--Define a table structure for clean (or pre-processed) data in our preferred data/output type 
DECLARE @tblCleanDatesAndThings TABLE 
    (
    date_effective date 
    , date_expiration date 
    ) 

--Gather our cleaned up data 
INSERT INTO @tblCleanDatesAndThings 
    SELECT date_effective, 
     date_expiration 
    FROM @tblDatesAndThings 
     WHERE ISDATE(date_effective) = 1 
     AND ISDATE(date_expiration) = 1 

--Apply our criteria to the clean data, for final output 
SELECT * FROM @tblCleanDatesAndThings 
    WHERE GETDATE() BETWEEN date_effective AND date_expiration 
1

因爲你effectiveexpiration是字符串年月日,你只需要GETDATE()轉換爲格式和比較。而就順便effectiveexpiration

WHERE CONVERT(VARCHAR(8), GETDATE(), 112) BETWEEN effective AND expiration 

不需要皈依,你應該考慮使用日期或日期時間數據類型,這2列

0

SQL服務器可能會感到困惑,因爲你想將DATEDATETIME比較,因爲GETDATE()返回後者。嘗試讓你在使用datetime,這樣的改變你的轉換:

CONVERT(datetime, date_effective, 112) as effective 
0

只是比較未轉化的價值 - 這樣

SELECT effective, expiration 
FROM 
(
    SELECT 
     CONVERT(date, date_effective, 112) as effective, 
     CONVERT(date, date_expiration, 112) as expiration, 
     date_effective, date_expiration 
    FROM ... 
) AS X 
WHERE GETDATE() BETWEEN date_effective AND date_expiration 
0
SELECT 
CONVERT(date, date_effective, 112) as effective, 
CONVERT(date, date_expiration, 112) as expiration 
FROM .. 
WHERE ISDATE(date_effective) and ISDATE(date_expiration)