Como obtenho a função SUM no MySQL para retornar '0' se nenhum valor for encontrado?


150

Digamos que eu tenha uma função simples no MySQL:

SELECT SUM(Column_1)
FROM Table
WHERE Column_2 = 'Test'

Se nenhuma entrada em Column_2 contiver o texto 'Test', essa função retornará NULL, enquanto eu gostaria que retornasse 0.

Estou ciente de que uma pergunta semelhante foi feita algumas vezes aqui, mas não consegui adaptar as respostas aos meus propósitos, por isso ficaria grato por alguma ajuda para resolver isso.


possível duplicata da Ajuda com MySQL SUM ()
JohnFx

Respostas:


305

Use COALESCEpara evitar esse resultado.

SELECT COALESCE(SUM(column),0)
FROM   table
WHERE  ...

Para vê-lo em ação, consulte este violino sql: http://www.sqlfiddle.com/#!2/d1542/3/0


Mais Informações:

Dadas três tabelas (uma com todos os números, uma com todos os nulos e outra com uma mistura):

SQL Fiddle

Configuração do Esquema do MySQL 5.5.32 :

CREATE TABLE foo
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO foo (val) VALUES
(null),(1),(null),(2),(null),(3),(null),(4),(null),(5),(null),(6),(null);

CREATE TABLE bar
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO bar (val) VALUES
(1),(2),(3),(4),(5),(6);

CREATE TABLE baz
(
  id    INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  val   INT
);

INSERT INTO baz (val) VALUES
(null),(null),(null),(null),(null),(null);

Consulta 1 :

SELECT  'foo'                   as table_name,
        'mixed null/non-null'   as description,
        21                      as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    foo
UNION ALL

SELECT  'bar'                   as table_name,
        'all non-null'          as description,
        21                      as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    bar
UNION ALL

SELECT  'baz'                   as table_name,
        'all null'              as description,
        0                       as expected_sum,
        COALESCE(SUM(val), 0)   as actual_sum
FROM    baz

Resultados :

| TABLE_NAME |         DESCRIPTION | EXPECTED_SUM | ACTUAL_SUM |
|------------|---------------------|--------------|------------|
|        foo | mixed null/non-null |           21 |         21 |
|        bar |        all non-null |           21 |         21 |
|        baz |            all null |            0 |          0 |

2
Obrigado Brad. Isso faz o trabalho bem.
Nick

1
SELECT SUM (IFNULL (coluna, 0)) DA tabela GROUP BY é algo mais correto? E se tivermos alguns valores IS NULL e alguns valores reais na "coluna"?
DarkSide

2
@ DarkSide: Absolutamente nada de inesperado.
Brad Christie

@BradChristie sim, você está absolutamente certo. SUM também funciona bem com valores NULL.
DarkSide

1
Esteja ciente de que while SUMfunciona como desejado AVGe COUNTpode produzir resultados diferentes ao receber NULLSolicitando o uso, COALESCEconforme sugerido pelo @DarkSide, dependendo do resultado desejado.
fyrye

65

Use IFNULLou COALESCE:

SELECT IFNULL(SUM(Column1), 0) AS total FROM...

SELECT COALESCE(SUM(Column1), 0) AS total FROM...

A diferença entre eles é que IFNULLé uma extensão do MySQL que recebe dois argumentos e COALESCEé uma função SQL padrão que pode receber um ou mais argumentos. Quando você tem apenas dois argumentos, o uso IFNULLé um pouco mais rápido, embora aqui a diferença seja insignificante, pois é chamada apenas uma vez.


3
@ Mark qual é a diferença b / w IFNULLou COALESCE?? você poderia explicar isso?
mo sean

1
PS. Para quem trabalha com o Postgres, ele suporta apenas coalesce.
Siddhartha

4

Não é possível obter exatamente o que você está perguntando, mas se você estiver usando uma função SUM agregada, o que implica que você está agrupando a tabela.

A consulta vale para MYSQL assim

Select IFNULL(SUM(COLUMN1),0) as total from mytable group by condition

Você agrupa por condição, mas não a devolve (você receberá várias quantidades de condições desconhecidas)?
Lluis Martinez
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.