【问题标题】:What is the difference between IFNULL and COALESCE in MySQL?MySQL 中的 IFNULL 和 COALESCE 有什么区别?
【发布时间】:2022-02-25 11:51:44
【问题描述】:
SELECT IFNULL(NULL, 'Replaces the NULL')
--> Replaces the NULL

SELECT COALESCE(NULL, NULL, 'Replaces the NULL')
--> Replaces the NULL

在这两个子句中,主要区别在于参数传递。 IFNULL 是两个参数,COALESCE 是多个参数。那么除此之外,这两者之间还有其他区别吗?

它在 MS SQL 中有何不同?

【问题讨论】:

  • IFNULL 检查单个参数。 COALESCE 使用 N 个参数。 COALESCE 在您有未知数量的要检查的值时很有用。 IFNULL 在您选择列并且知道它可以为空但您想用不同的值表示它时很有用。因此,这两个功能非常不同。至于 MSSQL 的区别——google 可以帮助你,你可以通过自己的研究快速获得这些信息。
  • @N.B.,引用 "IFNULL 检查单个参数。COALESCEN 参数一起使用。",对于 N = 2 的情况,两者作品。那你会用哪个?

标签: mysql sql sql-server


【解决方案1】:

两者的主要区别在于IFNULL 函数接受两个参数,如果不是NULL,则返回第一个参数;如果第一个参数是NULL,则返回第二个参数。

COALESCE函数可以带两个或多个参数并返回第一个非NULL参数,如果所有参数都为null,则返回NULL,例如:

SELECT IFNULL('some value', 'some other value');
-> returns 'some value'

SELECT IFNULL(NULL,'some other value');
-> returns 'some other value'

SELECT COALESCE(NULL, 'some other value');
-> returns 'some other value' - equivalent of the IFNULL function

SELECT COALESCE(NULL, 'some value', 'some other value');
-> returns 'some value'

SELECT COALESCE(NULL, NULL, NULL, NULL, 'first non-null value');
-> returns 'first non-null value'

更新: MSSQL 进行更严格的类型和参数检查。此外,它没有IFNULL 函数,而是ISNULL 函数,它需要知道参数的类型。因此:

SELECT ISNULL(NULL, NULL);
-> results in an error

SELECT ISNULL(NULL, CAST(NULL as VARCHAR));
-> returns NULL

另外,MSSQL 中的COALESCE 函数要求至少有一个参数不为空,因此:

SELECT COALESCE(NULL, NULL, NULL, NULL, NULL);
-> results in an error

SELECT COALESCE(NULL, NULL, NULL, NULL, 'first non-null value');
-> returns 'first non-null value'

【讨论】:

  • 一个挑剔:你不需要在 MSSQL 中的 COALESCE 中至少有一个非空值。您不能只使用 NULL 常量,但所有值都可以为空(例如,在查询中)。所以这没关系:COALESCE(NULL, ValueWhichIsNULL)。演示:sqlfiddle.com/#!6/3f5c7/2/0
【解决方案2】:

COALESCE 的优点

  • COALESCE 是 SQL 标准函数

    虽然IFNULL 是 MySQL 特定的,而它在 MSSQL (ISNULL) 中的等价物是 MSSQL 特定的。

  • COALESCE 可以处理两个或多个参数(实际上,它可以处理单个参数,但在这种情况下非常无用:COALESCE(a)a)。

    虽然 MySQL 的 IFNULL 和 MSSQL 的 ISNULLCOALESCE 的有限版本,但只能使用两个参数。

COALESCE 的缺点

  • 根据Transact SQL documentationCOALESCE 只是CASE 的语法糖,可以多次评估其参数。详细信息:COALESCE(a1, a2, …, aN)CASE WHEN (a1 IS NOT NULL) THEN a1 WHEN (a2 IS NOT NULL) THEN a2 ELSE aN END。这大大降低了COALESCE 在 MSSQL 中的用处。

    另一方面,MSSQL 中的ISNULL 是一个普通函数,不会多次计算其参数。 MySQL 和 PostgreSQL 中的 COALESCE 不会多次评估其参数。

  • 目前,我不知道 SQL 标准如何准确定义 COALESCE

    正如我们从前一点看到的那样,RDBMS 中的实际实现各不相同:有些(例如 MSSQL)使 COALESCE 多次评估其参数,有些(例如 MySQL、PostgreSQL)- 不这样做。

    c-treeACE,claims it's COALESCE implementation is SQL-92 compatible,说:“这个函数在 GROUP BY 子句中是不允许的。这个函数的参数不能是查询表达式。”我不知道这些限制是否真的在 SQL 标准之内。 COALESCE 的大多数实际实现(例如 MySQL、PostgreSQL)没有这样的限制。 IFNULL/ISNULL,作为普通函数,也没有这样的限制。

简历

除非您在特定 RDBMS 中遇到 COALESCE 的特定限制,否则我建议始终使用 COALESCE,因为它更标准、更通用。

例外情况是:

  • 在 MSSQL 中长时间计算的表达式或具有副作用的表达式(根据文档,COALESCE(expr1, …) 可能会计算两次 expr1)。
  • GROUP BY 中使用或与 c-treeACE 中的查询表达式一起使用。

【讨论】:

  • 可能还有一些技术数据库/驱动程序特定的差异。例如,用于 MySQL 的 ODBC 驱动程序导致 IFNULL(datetime1, datetime2) 表达式返回 System.DateTime,但 COALESCE(datetime1, datetime2)System.Byte[](至少在某些版本中,虽然它看起来像一个错误,当然)。
【解决方案3】:

SQL-Server 的区别:

  • 没有IFNULL() 函数,但有一个类似的ISNULL()

  • ISNULL 只接受 2 个参数,而 COALESCE 接受可变数量的参数

  • COALESCE 基于 ANSI SQL 标准,而 ISNULL 是专有的 TSQL 函数

  • ISNULLCOALESCE 的验证也不同。例如,ISNULLNULL 值将转换为 int,而对于 COAELSCE,您必须提供一个类型。例如:

    • ISNULL(NULL,NULL):是整数。

    • COALESCE(NULL,NULL) : 会抛出错误。

    • COALESCE(CAST(NULL as int),NULL) :有效并返回int。

  • 结果表达式的数据类型确定 - ISNULL 使用第一个参数类型,COALESCE 遵循 CASE 表达式规则并返回具有最高优先级的值类型。

【讨论】:

  • 你错了。 COALESCE(NULL, NULL) 不会抛出错误 - 它将返回 NULL。此外,OP 询问的是IFNULL 功能,而不是ISNULL - 请仔细阅读问题。哦,NULL 永远不会转换为 int
  • @AleksG praba 正在回答有关 SQL-Server 的问题,COALESCE(NULL,NULL) 确实会抛出错误:SQL-Fiddle
  • @ypercube 然后他需要在回答中说清楚。 OP 的问题的标题是 mysql 中 ifnull 和 coalesce 有什么区别? - 你在那里看到 sql-server 吗?
  • @AleksG 我看到一个[sql-server] 标记和最后一个问题:“它在 MSSql 中有何不同。” 但你是对的,回答者需要澄清答案仅适用于 SQL-Server。
  • @praba AleksG 是对的。在 MySql 中 COALESCE(NULL,NULL) 没有抛出任何错误。
【解决方案4】:

ifnull只能替换第一个参数的空值。而coalesce 可以用另一个值替换任何值。使用标准 SQL 中的coalesce,您可以使用许多参数来转换许多值。

根据下面的 cmets 编辑示例。

示例:coalesce(null, null, null, 'b*', null, 'null*') 返回 '​​b*' 并且不能与 ifnull 做。

【讨论】:

  • 参考上面例子中你给出的rdbms。MySql中的结果是“b”而不是“b*”
  • 好的,删除了我的 cmets。
【解决方案5】:

此 db2 SQL 不能与 COALESE 一起使用,我将看不到任何检索到的行。 由于我使用了 IFNULL 它按预期工作

select a.mbitno ,a.mbstqt,ifnull(b.apr,0)
from
( 
    select mmstcd,mbstat,mbfaci,mbwhlo,mbitno,mbstqt,MBALQT from libl.mitbal  inner join libl.mitmas on 
    mmcono=mbcono and mmitno=mbitno 
    where mbcono=200 and mbstat in ('20','50') and mmstcd>0  
)  
as a left join 
(
    select mlfaci,mlwhlo,mlitno,mlstas,sum(mlstqt) as APR from libl.mitloc where mlcono=200 and mlstas='2'
    group by mlfaci,mlwhlo,mlitno,mlstas
) 
b on b.mlfaci=a.mbfaci and b.mlwhlo=a.mbwhlo and b.mlitno=a.mbitno 
where a.mbitno in 'GWF0240XPEC' and a.mbstqt>0 and a.mbstqt<>ifnull(b.apr,0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 2014-08-03
    • 2011-03-21
    • 2011-07-30
    相关资源
    最近更新 更多