我正在尝试查看4个日期字段并选择最新的字段。一切都很好,直到我在一个没有任何东西的地方。然后我得到了一个
“从字符串转换日期和/或时间时转换失败。”错误。
有没有办法忽略空值?
Select AP.ID, AP.CERT_DATE as 'Cert Date', AP.Recert_Date as 'Recert Date', AP.Recert_Date2 as 'Recert Date 2', AP.Recert_Date3 as 'Recert Date 3',
CASE
When AP.CERT_DATE > AP.Recert_Date AND AP.CERT_DATE > AP.Recert_Date2 AND AP.CERT_DATE > AP.Recert_Date3 Then AP.CERT_DATE
When AP.Recert_Date > AP.CERT_DATE AND AP.Recert_Date > AP.Recert_Date2 AND AP.Recert_Date > AP.Recert_Date3 Then AP.Recert_Date
When AP.Recert_Date2 > AP.CERT_DATE AND AP.Recert_Date2 > AP.Recert_Date AND AP.Recert_Date2 > AP.Recert_Date3 Then AP.Recert_Date2
When AP.Recert_Date3 > AP.CERT_DATE AND AP.Recert_Date3 > AP.Recert_Date AND AP.Recert_Date3 > AP.Recert_Date2 Then AP.Recert_Date3
ELSE 'Attention'
END AS 'Most Recent Year'
FROM Profile AP
答案 0 :(得分:1)
如果您使用的是SQL Server 2012或更高版本,则开发人员更友好的方法是使用TRY_CONVERT,它允许检查(n)varchar是否表示特定格式的有效日期时间。
应用Javier的回答,你可以这样:
declare @minDate DATE = '19000101'
(SELECT Max(d) FROM (VALUES
(ISNULL(TRY_CONVERT(DATETIME, CERT_DATE), @minDate),
(Recert_Date),
(Recert_Date2),
(Recert_Date3)
) AS value(d)) as 'Most Recent Year'
(仅适用于varchars的TRY_CONVERT
)
但是,如果可能,请尝试将所有日期列设为DATE
或DATETIME2
,而不是VARCHAR
。
答案 1 :(得分:0)
如果您使用的是MSSQL 2008或更高版本,可以尝试一下吗?
SELECT AP.ID, AP.CERT_DATE as 'Cert Date', AP.Recert_Date as 'Recert Date', AP.Recert_Date2 as 'Recert Date 2', AP.Recert_Date3 as 'Recert Date 3',
(SELECT Max(d)
FROM (VALUES (CERT_DATE), (Recert_Date), (Recert_Date2), (Recert_Date3)) AS value(d)) as 'Most Recent Year'
FROM Profile AP
顺便说一下,关于您的错误,when
语句中的所有字段都是date
类型,字段else
语句是varchar
。您无法在案例结构中组合不同的类型。您应该将else
字段更改为默认日期而不是字符串,或者将when
语句中的所有字段转换为varchar
。
恕我直言,你的查询难以阅读且难以管理,所以我建议使用上面提到的替代查询。
编辑:如果你想进一步处理这个新专栏你可以做这样的事情(阿列克谢的例子更清洁):
SELECT A.ID, A.CERT_DATE as 'Cert Date', A.Recert_Date as 'Recert Date', A.Recert_Date2 as 'Recert Date 2', A.Recert_Date3 as 'Recert Date 3'
, ISNULL(CAST(MaxDate as varchar),'Attention') -- I would prefer following Alexei's approach by declaring previously a mindate variable and do: ISNULL(MaxDate, @MinDate) -- That way you can keep the date type output
, DATEDIFF (YY, MaxDate, GETDATE())
, Case When DATEADD (YY, DateDiff (YY, MaxDate, GETDATE()), MaxDate) > GETDATE () Then 1 Else 0 End
FROM
(
SELECT AP.ID, AP.CERT_DATE, AP.Recert_Date, AP.Recert_Date2, AP.Recert_Date3
(SELECT Max(d)
FROM (VALUES (CERT_DATE), (Recert_Date), (Recert_Date2), (Recert_Date3)) AS value(d)) as 'MaxDate'
FROM Profile AP
) A
在一天结束时,您将始终在同一个地方。您不能在同一列上组合varchar和日期类型。这就是为什么你需要将一个或另一个投射到另一种类型。 应用于Alexei的建议您可以使用默认的@MinDate,以便稍后检查该值并显示全局化的消息(如果您从.NET运行SP)