2011-06-29 22 views
7

Me gustaría que los agregados de un resultado vacío listo para ser 0. He intentado lo siguiente:agregada de un conjunto de resultados vacío

SELECT SUM(COALESCE(capacity, 0)) 
    FROM objects 
WHERE null IS NOT NULL; 

Resultado:

sum 
----- 

(1 row) 

los casos de preguntas: ¿no el trabajo anterior en Oracle, usando SUM(NVL(capacity, 0))?

+0

¿Qué error obtienes? –

Respuesta

8

De the documentation page sobre las funciones de agregado:

Cabe señalar que a excepción de count, estas funciones devuelven un valor nulo cuando no hay filas se seleccionan. En particular, sum sin filas devuelve nulo, no cero como uno podría esperar. La función coalesce se puede usar para sustituir cero por nulo cuando sea necesario.

Por lo tanto, si se quiere garantizar un valor devuelto, aplicar COALESCE al resultado de SUM, no a su argumento:

SELECT COALESCE(SUM(capacity), 0) … 

En cuanto a 'los casos de preguntas' Oracle, bueno, no hemos encontrado ninguna noción de valores NULL en la página de documento oficial (the one for 10.2, en particular), pero otras dos fuentes son inequívocos:

Es decir, no necesita aplicar NVL al capacity. (. Pero, al igual que con COALESCE en PostgreSQL, es posible que desee aplicarlo a SUM)

+0

¿No debería ser 'para sustituir nulo por cero' en lugar de' sustituir a cero por nulo'? Aunque no soy un hablante nativo. –

+0

@ VlastimilOvčáčík: Tampoco yo. ¡Ojalá fuera quien escribió ese pasaje en los documentos! :) En serio, sin embargo, esa frase es correcta en inglés. "Sustituir A por B" significa lo mismo que "reemplazar * o * sustituir B por A". Gramática inglesa: ¡imagínate! –

+0

¡Estás [correcto] (http://english.stackexchange.com/questions/23360/substitute-x-for-y)! Pero es complicado. –

5

El problema es que el agregado siempre devuelve una fila, incluso si no se agregaron filas (como es el caso en su consulta). Sumaste una expresión sobre ninguna fila. De ahí el valor nulo que está obteniendo.

probar este lugar:

select coalesce(sum(capacity),0) 
from objects 
where false; 
+1

puede simplificar eso con coalesce (suma (capacidad), 0) ya que sum() ignorará los valores NULL. – peufeu

+0

@peufeu: cierto, pero si su consulta real utiliza una combinación izquierda, null + cualquier cosa produce nulo, al igual que suma con un campo potencialmente nulo. –

+1

peufeu tiene razón. La unión dentro de su SUM es redundante. Ver la simulación del código de mi respuesta –

1

Sólo hacer esto:

SELECT COALESCE(SUM(capacity), 0) 
FROM objects 
WHERE null IS NOT NULL; 

Por cierto, se unen en el interior de SUMA es redundante, incluso si la capacidad es NULL , no hará que el resumen sea nulo.

A saber:

create table objects 
(
    capacity int null 
); 

insert into objects(capacity) values (1),(2),(NULL),(3); 

select sum(capacity) from objects; 

que devolverá un valor de 6, no nulo.

Y se unen dentro de una función agregada es un asesino en el rendimiento también, como su motor de RDBMS no puede simplemente extraer a través de todas las filas, se tiene que evaluar la columna de cada fila si su valor es nulo. He visto un poco de consulta OCD donde todas las consultas agregadas se fusionan en el interior, creo que el desarrollador original tiene un síntoma de Cargo Cult Programming, la consulta es muy poco útil. Eliminé la unión dentro de SUM, luego la consulta se volvió rápida.

0

Aunque este post es muy viejo, pero me gustaría actualizar lo que uso en tales casos

SELECT NVL(SUM(NVL(capacity, 0)),0) 
FROM objects 
WHERE false; 

Aquí NVL externa evita los casos cuando no hay ninguna fila del conjunto de resultados. Inner NVL se usa para valores de columnas nulas, considere el caso de (1 + nulo) y dará como resultado nulo. Por lo tanto, el NVL interno también es necesario de otra manera en el valor predeterminado de ajuste 0 de la columna.

Cuestiones relacionadas