Mysql - 转换非空值第 2 部分

Posted

技术标签:

【中文标题】Mysql - 转换非空值第 2 部分【英文标题】:Mysql - transforming non-null values part 2 【发布时间】:2016-03-31 19:51:05 【问题描述】:

In this question 我问mysql是否有一个函数,它接收两个参数并返回null,如果第一个是null,否则返回第二个参数。评论区有人说不存在这样的功能。考虑到它可以接收任何类型的参数并且返回值可以为 null 或与第二个参数的类型相同,我如何在 Mysql 中定义此函数?有没有可能?

【问题讨论】:

select case when arg1 is null then null else arg2 end 最简单的方法是(case when arg1 is not null then arg2 end)。您似乎想要的一个函数是来自 Oracle 的 nvl2() MySQL 支持COALESCE,如果我理解正确的话,这将适用。 【参考方案1】:

鉴于您的或要求,这是不可能的。

存储函数(用 SQL 编写)和用户定义函数(用 C 编写)的参数和返回值都是静态类型的。

当然,MySQL 在隐式转换方面非常灵活,但值仍然是类型化的。即使您对隐式转换没问题,也很难想象这种情况比看似显而易见的解决方案更可取。

IF(foo IS NULL,foo,bar) 足以满足此目的并正确保留基础类型,IF(foo IS NULL,NULL,bar) 几乎是一样的,尽管 foo 的类型会丢失(例如“它是一个 NULL DATETIME”)。

您以前拒绝过这些,原因并不直观。当一个目的可以通过内置实现时,重新发明***的动机就很难理解了。

【讨论】:

这不是我想要的,我想做一个只接收两个参数的函数,你只是在解释我应该习惯这个 if 函数,因为我无法实现我的目标。我想这样做的原因很简单,我有这种情况:coalesce(if(isNull(sale.id), null, 'related to a sale'), if(isNull(purchace.id), null, 'related to a purchase')...),因为我正在做一些左连接来获取支付上下文,出于某种原因,这超出了这个问题的范围。 Facepalm。你为什么不这么说?您的解决方案很简单:CASE WHEN sale.id IS NOT NULL THEN 'related to a sale' WHEN purchase.id IS NOT NULL THEN 'related to a purchase' ELSE 'related to funny cat videos' ENDCASE 表达式中的第一个匹配决定了结果...就像COALESCE() 的第一个非 NULL 参数一样。我的朋友,您似乎对我们提出了经典的XY problem,询问您尝试的解决方案,而不是实际问题。 感谢您的帮助。我想“包装空上下文本身”并只处理具体的内容,就像 Haskell 的 monad 思维方式一样,我不想要所有的样板,你展示的所有内容我已经考虑过,我想要知道我是否可以像这样coalesce(f(sale.id, 'related to a sale'), f(purchase.id, 'related to a purchase')) 解决它。这里的每个人都无法理解 nullabsence 的上下文,我想直观地对待它,就像 Haskell Maybe monad 一样,但是在 SQL 中...... 在 Perl 中,我的 $string = $this ||如果 $this 未定义或为空或为 false,则 $that 将 $string 设置为 $that,否则将 $string 设置为 $this。我之所以提到这一点,正是因为它相对无关紧要。这是 SQL,不是任何其他语言。 虽然我和其他人一样欣赏理论上优雅和/或直观/富有表现力的解决方案,但您似乎确实有点无情地击败了一匹死马。如果你问了你的实际问题,最直观和优雅的答案是我上面评论中的CASE 表达式。不过,我的回答不是“不要按你的方式做,而是按我的方式做”,而是 MySQL 不能满足你想要的,如果你坚持这个函数是数据类型不可知的。给定已知/固定类型,存储函数就足够简单了。【参考方案2】:

试试这个:

Select IF(ISNULL(arg1), null, arg2)

阅读有关Comparison Functions and Operators 和Control Flow Functions 的更多信息。

【讨论】:

它有很多样板文件,我已经在之前的回答中说明了您建议的方法。我想定义一个函数 myFunction(x, y) 来满足我的问题要求,而不是使用这个 IF 函数。

以上是关于Mysql - 转换非空值第 2 部分的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 按空值和非空值分组

数据库怎么用非空值填充为空值?

如何使用 php 从 mySQL DB 中的两个表中添加非空值?

mysql创建表时的空值和非空值设置有啥讲究

mysql 8 pivot 查询应该返回一个非空值

MySQL在分组后获得第一个非空值