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' END
。 CASE
表达式中的第一个匹配决定了结果...就像COALESCE()
的第一个非 NULL 参数一样。我的朋友,您似乎对我们提出了经典的XY problem,询问您尝试的解决方案,而不是实际问题。
感谢您的帮助。我想“包装空上下文本身”并只处理具体的内容,就像 Haskell 的 monad 思维方式一样,我不想要所有的样板,你展示的所有内容我已经考虑过,我想要知道我是否可以像这样coalesce(f(sale.id, 'related to a sale'), f(purchase.id, 'related to a purchase'))
解决它。这里的每个人都无法理解 null
或 absence
的上下文,我想直观地对待它,就像 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 部分的主要内容,如果未能解决你的问题,请参考以下文章