2011-02-10 1 views
2

Что будет SQL-эквивалент этого оператора C#?SQL-проверка для NULL в выражении WHERE (тернарный оператор?)

bool isInPast = (x != null ? x < DateTime.Now() : true)

Мне нужно построить пункт WHERE, который проверяет, что x < NOW() только если x IS NOT NULL. x - это datetime, который иногда должен иметь значение null, а не null в другое время, и я хочу, чтобы в предложении WHERE учитывались непустые значения и считалось, что значения null являются истинными.

Сейчас оговорка:

dbo.assignments.[end] < { fn NOW() }

Который работает для не-NULL случаев, но NULL значения всегда, кажется, делает выражение оценку лжи. Я пробовал:

dbo.assignments.[end] IS NOT NULL AND dbo.assignments.[end] < { fn NOW() }

И это, кажется, не имеют никакого эффекта.

+0

Ничего, это была проблема с моими данными. – cmv

ответ

0

Тот, который вы ищете, вероятно, CASE заявление

0

Вам нужно что-то вроде

WHERE X IS NULL 
OR X < NOW() 
+0

Я думаю, вы имеете в виду 'GetDate()' вместо 'Now()' для SQL Server. – Thomas

+0

Да, это правда, просто сохраняя его так же, как вопрос OP –

0

Есть два отдельных запросов, один, когда х нуль один, когда нет. Попытка сочетать два разных условия - это гарантированный шанс получить плохой план. Помните, что сгенерированный план должен работать для всех значений значений x, поэтому любая оптимизация на основе этого (сканирование диапазона по индексу) больше невозможна.

5

Для использования в ИНЕКЕ, вы должны проверить отдельно

where dbo.assignments.[end] is null or dbo.assignments.[end] < GetDate() 

или вы можете превратить аннулирует в дату (что всегда будет верно)

where isnull(dbo.assignments.[end],0) < GetDate() 

или вы можете сделать отрицательный тест против битового флага, полученного из ниже

where case when dbo.assignments.[end] < GetDate() then 0 else 1 end = 1 


Ниже приведено объяснение и как вы получите isInPast для предложения SELECT.

BOOL isInPast = (!? Х = нуль х < DateTime.Now(): правда)

логическое значение может иметь только один из двух результатов, истинным или ложным.
Присмотревшись по вашим критериям, то единственное условие для ложной когда

х!= Нуль & & х < Теперь

Учитывая тот факт, что становится легко перевод, учитывая, что в SQL, x < now может быть оценена только тогда, когда x!=null, поэтому только одно условие необходимо

isInPast = case when dbo.assignments.[end] < { fn NOW() } then 0 else 1 end 

(1 является истинным и 0 является ложным)

Не знаете, что такое { fn NOW() }, но если SQL Server должен предоставить текущее время, используйте либо GETDATE(), либо если вы работаете с данными UTC, используйте GETUTCDATE()

isInPast = case when dbo.assignments.[end] < GetDate() then 0 else 1 end 
Смежные вопросы