2013-07-25 9 views
35

Próbuję wykonać funkcję typu instrukcji IF w serwerze SQL.Oświadczenie SQL Server Case, gdy IS NULL

Tam, gdzie w polu jest NULL, chcę, aby wziął pole z jednej z tabel i dodał do niego 10 dni.

I jeśli to możliwe, utwórz kolejną kolumnę i dodaj 30 dni.

SELECT DISTINCT 
    B.[ID], 
    MAX(A.[START DATE]), 
    B.[STAT], 
    C.[POST DATE], 
    CASE 
      WHEN (C.[POST DATE] BETWEEN C.[EVENT DATE]+10 AND C.[EVENT DATE]+30) THEN 'GOOD' 
      END AS [BETTER VISIT], 
    CASE 
      WHEN B.[STAT] IS NULL THEN (C.[EVENT DATE]+10) 
      ELSE '-' 
      END AS [DATE] 
FROM 
    #TEMP1 A 
    FULL OUTER JOIN #TEMP2 B 
    ON A.[ID]=B.[ID] 
    FULL OUTER JOIN #TEMP3 C 
    ON A.[ID]=C.[ID] 
GROUP BY 
    B.[ID], 
    B.[STAT], 
    C.[POST DATE], 
    C.[EVENT DATE] 
ORDER BY 
    A.[START DATE] DESC 

Rezultatem będzie wyglądać trochę jak:

ID START DATE STAT POST DATE BETTER VISIT DATE   DATE2 
    --------------------------------------------------------------------------- 
    1 2013-01-01 GOOD 2013-11-01 GOOD   -   - 
    2 2013-03-01 NULL NULL   NULL   2013-03-11 2013-03-31 
+1

Co jest nie tak z wyjściem you” Dostajesz teraz? –

+0

Msg 242, poziom 16, Stan 3, wiersz 1 Konwersja typu danych varchar na typ danych datetime spowodowała przekroczenie zakresu wartości. – caffaddt

+0

IsNull może pomóc. http://msdn.microsoft.com/en-us/library/ms184325.aspx – Oliver

Odpowiedz

49
CASE WHEN B.[STAT] IS NULL THEN (C.[EVENT DATE]+10) -- Type DATETIME 
    ELSE '-'           -- Type VARCHAR 
    END AS [DATE] 

Musisz wybrać jeden rodzaj lub inny dla pola, typ pola nie można zmieniać przez rząd. Najprościej jest usunąć ELSE '-' i pozwolić mu domyślnie uzyskać wartość NULL zamiast tego dla drugiego przypadku.

+0

Dzięki, spróbuję tego jutro. – caffaddt

+0

Próbowałem to i kwerendy działa, ale zwraca wartość NULL zamiast wartości [EVENT DATE] +10 w polach [STAT], które są NULL – caffaddt

+0

@caffaddt Czy można ustawić SQLfiddle z przykładowymi danymi? Poprawiłem tylko składnię zapytania, nie widzę logiki w pożądanym wyniku, nie widząc danych wejściowych. –

1

Twój łącznik w instrukcji ELSE nie jest akceptowany w kolumnie, która jest definiowana w ramach typu danych datetime. Można było albo:

a) owinąć wokół obsady [STAT] Pole do konwertowania go do reprezentacji varchar z datą

b) używać DateTime jak 9999-12-31 do wartości indziej.

4
case isnull(B.[stat],0) 
    when 0 then dateadd(dd,10,(c.[Eventdate])) 
    end 

możesz dodać instrukcję else, jeśli chcesz dodać 30 dni do tego samego.

+0

Próbowałem tego i otrzymałem ten komunikat: Msg 245, poziom 16, stan 1, wiersz 1 Konwersja nie powiodła się podczas przekształcania wartości varcharnej "STAT" na typ danych int. – caffaddt

+0

spróbuj użyć funkcji przesyłania lub konwertowania, aby zmienić typ danych do porównania. –

9

Zgadzam się z Joachimem, że należy zastąpić łącznik przez NULL. Ale jeśli naprawdę chcesz myślnik, konwertować datę do łańcucha:

(CASE WHEN B.[STAT] IS NULL 
     THEN convert(varchar(10), C.[EVENT DATE]+10, 121) 
     ELSE '-' 
END) AS [DATE] 

Również distinct jest zbędna w swoim oświadczeniu select. group by robi to już za Ciebie.

+0

To działa, ale nie zwraca wartości dla DATE, po prostu daje wszystko zero. – caffaddt

1

W tej sytuacji można użyć ISNULL() funkcji zamiast wyrażenia CASE

ISNULL(B.[STAT], C.[EVENT DATE]+10) AS [DATE] 
2

Można użyć IIF (myślę z SQL Server 2012)

SELECT IIF(B.[STAT] IS NULL, C.[EVENT DATE]+10, '-') AS [DATE]