ISNULL дважды для одного и того же столбца

Можно ли дважды использовать ISNULL для одного и того же столбца?

ISNULL(ISNULL(column, SELECT sum(column2) FROM table WHERE type = '1')), SELECT sum(column2) FROM table WHERE type = '2'))

Или я должен делать это по-другому с IF ELSE как-то? Как бы это выглядело?


person mediasurface    schedule 20.08.2013    source источник
comment
@JoachimIsaksson Извините, похоже, это другая СУБД.   -  person user4035    schedule 20.08.2013
comment
@user4035 user4035 Похоже на ISNULL() SQL Server, но я думаю, что он может существовать и в других базах данных.   -  person Joachim Isaksson    schedule 21.08.2013
comment
@JoachimIsaksson Да, это SQL Server. В MySQL соответствующий оператор называется IFNULL.   -  person user4035    schedule 21.08.2013


Ответы (3)


Посмотрите на coalesce оператор. Затем ваш запрос становится:

COALESCE(column, 
    (SELECT sum(column2) FROM table WHERE type = '1'), 
    (SELECT sum(column2) FROM table WHERE type = '2'))

Он возвращает первый ненулевой результат из своих аргументов.

person Community    schedule 20.08.2013
comment
В моем случае я хочу получить ненулевое значение только в том случае, если значение равно нулю. С COALESCE он вернет первое незначение из своих аргументов. Я неправильно понял COALESCE или его можно написать так, чтобы он принимал первое ненулевое значение из аргументов, только если исходное значение равно нулю? - person mediasurface; 21.08.2013
comment
можно ли его написать так, чтобы он принимал только первое ненулевое значение из аргументов, если исходное значение равно нулю? Если исходное значение равно null, оно возьмет первое ненулевое значение из своих аргументов. Если исходное значение не равно null, возвращается исходное значение. Я не уверен, что понимаю ваш вопрос. - person ; 21.08.2013

Да, это возможно.

(Проблема, которую я вижу с выражением в вопросе, - это несбалансированные скобки; две дополнительные закрывающие скобки)

Функция ISNULL принимает два аргумента. Любой из этих аргументов (или оба) могут быть выражениями, а функция ISNULL является выражением. Так что да, вы можете вкладывать функции ISNULL на два, три, четыре или более уровней, как вам нужно.

Оператор SELECT, который возвращает одну строку, содержащую один столбец, может (обычно) использоваться как выражение. И несколько операторов SELECT (подзапросов) в запросе могут ссылаться на одну и ту же таблицу (таблицы) и один и тот же столбец (столбцы).

Во многих случаях, когда мы видим запрос такого типа, он указывает либо на плохо работающую модель, либо на поиск другого способа получения эквивалентного результата.

ИЗМЕНИТЬ

Как указывалось в других ответах, более переносимая функция COALESCE, соответствующая стандарту ANSI, может использоваться для возврата эквивалентного результата.

Эти три выражения эквивалентны:

ISNULL(ISNULL(a,b),c) 
ISNULL(a,ISNULL(b,c)) 
COALESCE(a,b,c)

которые также эквивалентны этим (излишне избыточным) выражениям:

COALESCE(COALESCE(a,b),c)
COALESCE(a,(COALESCE(b,c))

Прецедент:

create table tst (id int, a int, b int, c int);
insert into tst values 
(1,NULL,NULL,NULL)
,(2,21,NULL,NULL)
,(3,NULL,32,NULL)
,(4,NULL,NULL,43)
,(5,51,52,NULL)
,(6,61,NULL,63)
,(7,NULL,72,73)
,(8,81,82,83);

-- SQL Server
SELECT ISNULL(ISNULL(a,b),c) AS t1 
     , ISNULL(a,ISNULL(b,c)) AS t2
     , COALESCE(a,b,c)       AS t3
  FROM tst
 ORDER BY id

-- MySQL
SELECT IFNULL(IFNULL(a,b),c) AS t1 
     , IFNULL(a,IFNULL(b,c)) AS t2
     , COALESCE(a,b,c)       AS t3
  FROM tst
 ORDER BY id

-- Oracle
SELECT NVL(NVL(a,b),c)       AS t1 
     , NVL(a,NVL(b,c))       AS t2
     , COALESCE(a,b,c)       AS t3
  FROM tst
 ORDER BY id
person spencer7593    schedule 20.08.2013
comment
Вы рекомендуете использовать ISNULL таким образом, или вы имеете в виду, что, исходя из вашего опыта, это не работает должным образом? - person mediasurface; 21.08.2013
comment
@mediasurface: я думаю, что вы можете использовать ISNULL. Выражение в вопросе в порядке (кроме несоответствующих скобок), если оно возвращает нужный вам набор результатов. Как указывалось в других ответах, вы можете добиться того же результата, используя более переносимую функцию COALESCE, соответствующую стандарту ANSI. - person spencer7593; 21.08.2013

Попробуйте использовать COALESCE (если вы используете SQL Server). http://msdn.microsoft.com/en-us/library/ms190349.aspx

Это даст вам первое ненулевое значение из списка значений. Вам также нужна дополнительная помощь в структурировании SQL?

person John Tabernik    schedule 20.08.2013
comment
В моем случае я хочу получить ненулевое значение только в том случае, если значение равно нулю. С COALESCE он вернет первое незначение из своих аргументов. Я неправильно понял COALESCE или его можно написать так, чтобы он принимал первое ненулевое значение из аргументов, только если исходное значение равно нулю? - person mediasurface; 21.08.2013
comment
Вы правильно читаете ОБЪЕДИНЕНИЕ. Если вам нужно убедиться, что вы возвращаете только те строки, где результат не будет нулевым, вы можете обработать это в своем предложении WHERE, проверив (Value1 IS NOT NULL ИЛИ Value2 IS NOT NULL ИЛИ и т. д.). Это гарантирует, что ваши результаты будут включать только строки, которые дадут ненулевое значение. Но... вы также можете поместить запрос, который вы написали, в другой запрос (сделав его подзапросом) и указать, что вы хотите получить только те строки, где результат COALESCE не равен нулю. Я могу объяснить это подробнее, если это не имеет смысла. - person John Tabernik; 21.08.2013