2016-04-18 17 views
0

私は4つの日付フィールドを見て、最新のものを選択しようとしています。私はそれが何もないフィールドを打つまで、すべてが素晴らしい作品です。次に、私はケースのSQL変換エラー文

"文字列から日付や時刻を変換すると変換に失敗しました。"エラー。

nullを無視する方法はありますか?

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

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としてキャストする必要があります。

IMHOあなたのクエリは読みにくく、メインテナンスが難しいので、上記の代替クエリを使用することをお勧めします。

編集:あなたは新しい列は、あなたがこのような何かを行うことができ、プロセスを促進したい場合(アレクセイの例がある非常にクリーン):

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と日付の型を同じ列に組み合わせることはできません。そういうわけで、あなたはもう片方を他のタイプにキャストする必要があります。 アレクセイの勧告を適用すると、既定の@MinDateを使用して後でその値を確認し、グローバル化されたメッセージを表示できます。

+0

これはうまくいくように見えますが、私は別の式を呼び出すことができるので、列は何ですか?私は、この新しい列は、私の「年」の計算にうまく収まるだろうと思ったが、私はその新しい列を呼び出す方法を理解することはできません(YY、AP.Recert_Date、GETDATE()) - 。 \t \tケース \t \t \tするとDATEADD( YY、DateDiff関数(YY、AP.Recert_Date、GETDATE())、AP.Recert_Date)> GETDATE()すると1 \t \t \tエルス0 \t \tエンド – DerFox

+0

は私が何をしようとしていた何 – Javier

+0

上記の私の編集をチェックは減算今日のですMaxDateの列名が無効な列名 – DerFox

1

SQL Server 2012以降を使用している場合より開発者に優しいアプローチは、TRY_CONVERTを使用することです。これにより、a(n)varcharが特定の形式の有効な日付時刻を表すかどうかを確認できます。ハビエルの答えを適用

、あなたはこのような何か持つことができます。

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' 

(のみのvarcharためTRY_CONVERTを適用)

を可能ただし、タイプDATEであることがすべての日付列を持つようにしようとか、 DATETIME2VARCHARではありません。