Как получить функцию SUM в MySQL, чтобы она возвращала '0', если значения не найдены?

150

Скажем, у меня есть простая функция в MySQL:

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

Если никакие записи в Column_2 не содержат текст «Test», то эта функция возвращается NULL, в то время как я хотел бы, чтобы она возвращала 0.

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

Ник
источник
возможный дубликат справки с MySQL SUM ()
JohnFx

Ответы:

305

Используйте, COALESCEчтобы избежать этого результата.

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

Чтобы увидеть это в действии, пожалуйста, посмотрите эту скрипту sql: http://www.sqlfiddle.com/#!2/d1542/3/0


Больше информации:

Имеются три таблицы (одна со всеми числами, одна со всеми нулями и одна со смесью):

SQL Fiddle

Настройка схемы 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);

Запрос 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

Результаты :

| 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
Спасибо бред Это хорошо делает работу.
Ник
1
Разве SELECT SUM (IFNULL (column, 0)) из таблицы GROUP BY не является чем-то более правильным? Что если у нас есть некоторые значения IS NULL и некоторые реальные значения в столбце?
DarkSide
2
@DarkSide: абсолютно ничего неожиданного.
Брэд Кристи
@BradChristie: да, ты абсолютно прав. SUM также отлично работает со значениями NULL.
DarkSide
1
Имейте в виду, что while SUMработает так , как нужно, AVGи COUNTможет давать разные результаты при получении, NULLпредлагая использовать COALESCEв соответствии с предложением @DarkSide, в зависимости от желаемого результата.
fyrye
65

Используйте IFNULLили COALESCE:

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

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

Разница между ними заключается в том, что IFNULLэто расширение MySQL, которое принимает два аргумента, и COALESCEявляется стандартной функцией SQL, которая может принимать один или несколько аргументов. Когда у вас есть только два аргумента, использование IFNULLнемного быстрее, хотя здесь разница незначительна, так как он вызывается только один раз.

Марк Байерс
источник
3
@ Марк, какая разница ч / б IFNULLили COALESCE?? не могли бы вы объяснить это ??
Мо Шон
1
PS. Для тех, кто работает с Postgres, он поддерживает только coalesce.
Сиддхартха
4

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

Запрос идет для MYSQL, как это

Select IFNULL(SUM(COLUMN1),0) as total from mytable group by condition
Саши Кант
источник
Вы группируете по условию, но не возвращаете его (вы получите кучу неизвестных условий)?
Луис Мартинес