ISNULL() возвращает NULL

Почему следующий простой запрос возвращает null, когда нет совпадающих строк (<Condition> не соответствует ни одной строке)?

SELECT ISNULL(MyField, 0) FROM [MyTable] WHERE <Condition>

Я тоже пробовал COALESCE() с такими же результатами. Как я могу вернуть ноль, если нет совпадающих строк?


person dotNET    schedule 07.01.2015    source источник
comment
если <Condition> не выполнено, то строки не будет. Использование count(*) вернет количество совпадающих строк, если строки нет, то будет показано 0.   -  person Bharadwaj    schedule 07.01.2015
comment
@Bharadwaj: Я знаю это, поэтому я и задал вопрос. Как я могу вернуть ноль в этом случае?   -  person dotNET    schedule 07.01.2015
comment
Используйте IF @@ROWCOUNT > 0 ... См. msdn.microsoft.com/en-us/library/ms187316.aspx   -  person PM 77-1    schedule 07.01.2015
comment
SELECT count(*) FROM [MyTable] WHERE <Condition> даст 0, если строки не совпадают   -  person Bharadwaj    schedule 07.01.2015
comment
Просто проверьте, вернул ли запрос строку в логике вашей программы.   -  person juergen d    schedule 07.01.2015
comment
Спасибо. Я могу придумать другие обходные пути, которые требуют нескольких операторов. Я искал какую-нибудь встроенную/встроенную функцию, которая справилась бы с ситуацией. Сначала я считал, что ISNULL() уже справляется с ситуацией, но теперь похоже, что это невозможно.   -  person dotNET    schedule 07.01.2015


Ответы (3)


Это будет работать, если вы ожидаете, что condition уменьшит набор результатов до 0 или 1 строки:

SELECT ISNULL((SELECT MyField FROM [MyTable] WHERE <Condition>),0)

То есть создайте внешний запрос без предложения FROM (которое, следовательно, всегда будет генерировать ровно одну строку), а затем используйте подзапрос для получения 0 или 1 строки фактических данных.

person Damien_The_Unbeliever    schedule 07.01.2015
comment
Блестящий. Это однострочник и простое решение простой проблемы. Однако мне интересно, почему ISNULL ведет себя по-разному при применении к подзапросу и при применении к полю, даже если количество возвращаемых строк равно нулю в обоих случаях. - person dotNET; 07.01.2015
comment
@dotNET - как я уже сказал, мой внешний запрос имеет одну строку, а не ноль. Предложение SELECT — это описание того, что делать с каждой строкой в ​​наборе результатов. Если у него нет строк для обработки, он выполнит свою работу ноль раз. - person Damien_The_Unbeliever; 07.01.2015
comment
Упс. Я вижу это сейчас. Огромное спасибо. - person dotNET; 07.01.2015

Использовать это:

SELECT ISNULL(COUNT(MyField), 0) FROM [MyTable] WHERE <Condition>

Он вернет 0, если строка отсутствует.

person SanyTiger    schedule 07.01.2015
comment
Но он вернет количество, если условие выполнено. :) - person dotNET; 07.01.2015
comment
COUNT всегда дает номер, никогда не будь null, афаик - person Bharadwaj; 07.01.2015
comment
@Bharadwaj: Вы не поняли. Я говорю, что он не вернет MyField при выполнении условия. Таким образом, это решение не делает именно то, что должен делать рассматриваемый запрос. - person dotNET; 07.01.2015
comment
@DotNET Я понял твою точку зрения, я думаю об этом. Насколько я думаю, вам может понадобиться использовать Exist() с блоком if-else - person Bharadwaj; 07.01.2015

Вы не можете преобразовать 0 rows в 1 row with a null value с помощью какой-либо встроенной функции sql, поскольку это может привести к неправильной интерпретации данных.

Но вы можете настроить свой результат, используя приведенную ниже логику (так же, как и в .net).

If (select COUNT(MyField) FROM [MyTable] WHERE <Condition>)=0
select 0 as [MyField]
else
SELECT ISNULL(MyField, 0) as [MyField] FROM [MyTable] WHERE <Condition>
person Deepak Mishra    schedule 07.01.2015