我在SQL Server 2008中工作。我有一个包含两列存储日期值的表,但列本身是varchar。 (我知道,这是不好的做法,但我不拥有该表。)这两列中的一些记录是NULL。我试图将两列相互比较。因此,为了进行比较,我需要进行CONVERT。但是,CONVERT在遇到NULL时失败。当遇到NULL时,我如何实质上阻止CONVERT发生?我的核心查询如下:
SELECT
col1
FROM table_a
WHERE
CONVERT(date, col2, 101) > CONVERT(date, col3, 101)
我尝试使用IN子句进行内部查询(即内部查询仅返回非NULL记录),但这失败了,因为查询优化器似乎独立运行两个查询,即它在所有记录上运行CONVERT ,这会导致失败。我还尝试了一个自连接(即,只返回表的第一个实例中的记录,其中记录在表的第二个实例中不为空)。但是,由于内部查询场景中存在同样的问题,这也失败了。
答案 0 :(得分:4)
试试这个:
SELECT
col1
FROM table_a
WHERE
case
when col2 is null or col3 is null then 0
when CONVERT(date, col2, 101) > CONVERT(date, col3, 101) then 1
end = 1
此方法可防止空字符串被转换(或尝试进行),并允许您决定在其中一个或另一个cols为空时您还想做什么。
编辑:第一个版本在case语句中包含语法错误 - 现在应该修复这些错误。为仓促打字道歉,而不是SQLFiddling它。
答案 1 :(得分:0)
尝试
SELECT * FROM #Tmp
WHERE
col2 IS NULL OR col3 IS NULL OR
CONVERT(DATETIME, col2, 101) > CONVERT(DATETIME, col3, 101)
我在 SQL 2005 中尝试了以下查询,其工作正常,没有任何错误,但它返回没有null
的所有记录。上面的查询也会返回null
记录
SELECT * FROM #Tmp WHERE CONVERT(DATETIME, col2, 101) > CONVERT(DATETIME, col3, 101)
答案 2 :(得分:0)
试试这个:(包含样本数据)
DECLARE @TABLE TABLE
(
SomeText VARCHAR(50),
Date01 VARCHAR(50),
Date02 VARCHAR(50)
)
INSERT INTO @TABLE VALUES('Good Date 01','10/01/2014','12/30/2014')
INSERT INTO @TABLE VALUES('Early Date 01','10/01/2014','12/30/2013')
INSERT INTO @TABLE VALUES('Good Date 02','10/01/2013','10/01/2014')
INSERT INTO @TABLE VALUES('Bad Data 01',NULL,'12/30/2014')
INSERT INTO @TABLE VALUES('Bad Data 02','10/01/2014',NULL)
INSERT INTO @TABLE VALUES('Bad Data 03',NULL,NULL)
SELECT
SomeText,
DATEDIFF(D,CONVERT (DATE, Date01, 101) , CONVERT (DATE, Date02, 101)) AS DELTA
FROM
@TABLE
WHERE
1 = 1
AND ISDATE(Date01) = 1
AND ISDATE(Date02) = 1
and DATEDIFF(D,CONVERT (DATE, Date01, 101) , CONVERT (DATE, Date02, 101)) < 0
ISDATE(Date01)和ISDATE(Date02)删除转换函数尝试丢失的数据点。