2016-08-25 118 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)