Суммировать столбцы с нулевыми значениями в Oracle

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

Структура таблицы

hours_t
type     craft    regular       overtime
 A         1        5              0
 A         1        3              1
 B         2        9            <null>
 B         1        4              4

Запрос

select type, craft, sum(regular + overtime) as total_hours
from hours_t
group by type, craft
order by type, craft

Нежелательные результаты

type   craft   total_hours
  A      1          9
  B      1          8
  B      2        <null>

Желаемые результаты

type    craft   total_hours
  A       1          9
  B       1          8
  B       2          9

Ответов (9)

Решение
select type, craft, sum(nvl(regular,0) + nvl(overtime,0)) as total_hours
from hours_t
group by type, craft
order by type, craft

Код:

select type, craft, sum(coalesce( regular + overtime, regular, overtime)) as total_hours
from hours_t
group by type, craft
order by type, craft

В некоторых случаях также требуется nvl (sum (column_name), 0). Вы можете рассмотреть свои сценарии.

Например, я пытаюсь получить сумму определенного столбца из определенной таблицы на основе определенных условий. Исходя из условий,

  1. в таблице существует одна или несколько строк. В этом случае мне нужна сумма.
  2. строк не существует. В этом случае я хочу 0.

Если вы используете здесь sum (nvl (column_name, 0)), это даст вам null. Возможно, вам понадобится nvl (sum (column_name), 0).

Это может потребоваться, особенно когда вы передаете этот результат, скажем, в java, имея тип данных как число, потому что тогда это не потребует специальной обработки null.

Без group by SUM(NVL(regular, 0) + NVL(overtime, 0)) выдаст ошибку, и чтобы избежать этого, мы можем просто использовать NVL(regular, 0) + NVL(overtime, 0)

NVL (значение, по умолчанию) - это функция, которую вы ищете.

select type, craft, sum(NVL(regular, 0) + NVL(overtime, 0) ) as total_hours
from hours_t
group by type, craft
order by type, craft

В Oracle есть 5 функций, связанных с NULL:

  1. NVL
  2. NVL2
  3. КОЛЕСЦЕ
  4. NULLIF
  5. LNNVL

NVL :

NVL(expr1, expr2)

NVL позволяет вам заменить null (возвращенный как пустое) на строку в результатах запроса. Если expr1 имеет значение null, NVL возвращает expr2. Если expr1 не равно нулю, тогда NVL возвращает expr1.

NVL2 :

NVL2(expr1, expr2, expr3)

NVL2 позволяет определить значение, возвращаемое запросом, в зависимости от того, является ли указанное выражение нулевым или ненулевым. Если expr1 не равно нулю, NVL2 возвращает expr2. Если expr1 имеет значение NULL, NVL2 возвращает expr3.

КОЛЕСЦЕ

COALESCE(expr1, expr2, ...)

COALESCE возвращает первое ненулевое выражение в списке выражений. По крайней мере, одно выражение не должно быть буквальным NULL. Если все вхождения expr оцениваются как null, функция возвращает null.

NULLIF

NULLIF(expr1, expr2)

NULLIF сравнивает expr1 и expr2. Если они равны, функция возвращает null. Если они не равны, функция возвращает expr1. Вы не можете указать буквальный NULL для expr1.

LNNVL

LNNVL(condition)

LNNVL предоставляет краткий способ оценки условия, когда один или оба операнда условия могут быть нулевыми.

Дополнительная информация о функциях Oracle SQL

Вам нужно использовать функцию NVL, например

СУММ (NVL (обычный, 0) + NVL (сверхурочная работа, 0))

Другие ответы относительно использования nvl () верны, но, похоже, ни один из них не затрагивает более важный момент:

Должны ли у вас вообще быть NULL в этом столбце?

Имеют ли они значение кроме 0?

Это похоже на тот случай, когда у вас должно быть НЕ NULL DEFAULT 0 в столбце

select type, craft, sum(NVL(regular, 0) + NVL(overtime, 0)) as total_hours
from hours_t
group by type, craft
order by type, craft

Высоко оцененный ответ с NVL полностью действителен. Если вы заинтересованы в том, чтобы сделать свой SQL-код более переносимым, вы можете использовать CASE, который поддерживается одним и тем же синтаксисом как в Oracle, так и в SQL Server:

select 
  type,craft,
  SUM(
    case when regular is null
         then 0
         else regular
    end
    +
    case when overtime is null
         then 0
         else overtime
    end
  ) as total_hours
from 
  hours_t
group by
  type
 ,craft
order by
  type
 ,craft