2009-02-26 30 views
23

Quiero agregar dos números pero cuando uno de esos números es nulo, el resultado es nulo. Hay alguna forma de evitar esto. Simplemente podría hacerlo en el código, pero preferiría hacerlo en la consulta. Esta es una base de datos de Oracle.Sumar columnas con valores nulos en oráculo

La estructura de la tabla

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

la consulta

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

Los resultados no deseados

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

El quería resultados

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

Por el camino, por favor no borre sus comentarios, si se dio una respuesta;) –

+0

borré el comentario porque la respuesta fue cambiada. –

Respuesta

44
select type, craft, sum(nvl(regular,0) + nvl(overtime,0)) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 
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 
46

NVL (valor por defecto) es la función que busca.

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 tienen 5 funciones relacionadas con NULL-:

  1. NVL
  2. NVL2
  3. COALESCE
  4. NULLIF
  5. LNNVL

NVL:

NVL(expr1, expr2) 

NVL le permite reemplazar nula (devuelto como un espacio en blanco) con una cadena en los resultados de una consulta. Si expr1 es nulo, NVL devuelve expr2. Si expr1 no es nulo, NVL devuelve expr1.

NVL2:

NVL2(expr1, expr2, expr3) 

NVL2 le permite determinar el valor devuelto por una consulta basada en si una expresión especificada es nulo o no nulo. Si expr1 no es nulo, entonces NVL2 devuelve expr2. Si expr1 es nulo, entonces NVL2 devuelve expr3.

COALESCE

COALESCE(expr1, expr2, ...) 

COALESCE devuelve el primer expr no nulo en la lista de expresiones. Al menos un expr no debe ser el NULL literal. Si todas las ocurrencias de expr se evalúan como nulas, la función devuelve null.

NULLIF

NULLIF(expr1, expr2) 

NULLIF compara expr1 y expr2. Si son iguales, entonces la función devuelve nulo. Si no son iguales, la función devuelve expr1. No puede especificar el NULL literal para expr1.

LNNVL

LNNVL(condition) 

LNNVL proporciona una manera concisa para evaluar una condición cuando uno o ambos operandos de la condición puede ser nulo.

Más información sobre Oracle SQL Functions

+0

Se podría haber tirado en CASE y DECODE está completo;) –

1

Es necesario utilizar la función NVL, por ejemplo,

SUM (NVL (regular, 0) + NVL (horas extras, 0))

9

Las otras respuestas relacionadas con el uso de NVL() son correctos, sin embargo ninguno parece abordar un punto más saliente:

¿Deberías incluso tener NULLs en esta columna?

¿Tienen un significado distinto de 0?

Este parece ser un caso en el que usted debe tener un defecto no NULL 0 on th eColumn

+0

El primer objetivo de lo que debe responder a la OP. Los programadores tienen una necesidad. Esa necesidad es tener una pregunta respondida. ¿Sabes si BerekBryan tiene la capacidad de cambiar la columna? ¿Ha conocido a la persona que puede cambiarlo? Sé que todos queremos mostrar lo listos que somos, pero sigamos con el OP –

+2

@ Mark Brady, realmente no estoy de acuerdo. No es "lo inteligentes que somos", sino que sugiere formas alternativas de abordar el problema. El OP puede o no tener la capacidad de cambiar la columna, pero el comentario es útil (si no es para él, posiblemente para otros que lean este hilo). –

+2

@cletus, creo que esto es más apropiado como un comentario sobre la pregunta que como una respuesta separada. –

4

La respuesta de primer nivel con NVL es totalmente válida. Si usted tiene algún interés en hacer que su código SQL más portátil, es posible que desee utilizar el caso, que se apoya con la misma sintaxis tanto en Oracle y 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 
0

Código:

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

Ayuda formatear el código un poco y explica lo que hace para aquellos interesados ​​en saber cómo funciona su respuesta – ochi

Cuestiones relacionadas