CONVERT仅限NOT NULL记录

时间:2014-10-29 17:16:43

标签: sql-server

我在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 ,这会导致失败。我还尝试了一个自连接(即,只返回表的第一个实例中的记录,其中记录在表的第二个实例中不为空)。但是,由于内部查询场景中存在同样的问题,这也失败了。

3 个答案:

答案 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)删除转换函数尝试丢失的数据点。