DuckDB:函数链式调用

我最喜欢DuckDB的一点是:创新式SQL语法。最近的一个发现(至少对我来说)是,可以使用点操作符将函数链接起来,就像在许多通用编程语言中一样。在本文中,我们将探索该功能。

从嵌套查询开始

在这里插入图片描述

首先从嵌套查询语句开始:

FROM (SELECT unnest(range(1,50,5)) AS num)
SELECT
  num,
  factorial(
    CAST(
      log2(
        power(
          sqrt(num),
          3
        )
      ) AS INTEGER
    )
  ) AS val; 

这个查询是做什么的?对于从1到50的数字,以5为步:

  • 计算平方根
  • 把该值的三次方
  • 计算该值的对数
  • 将其转换为整数
  • 最后计算阶乘

上面代码相当难以阅读,如果没有在单独行上格式化会更难懂。你必须从中间开始,然后仔细向外扩展。

链式调用

我发现从左到右阅读代码要容易得多,这就是函数链让我们做的。它有效地改写了:

## 一般调用
fn(arg1, arg2, arg3, ...)
## 链式调用
arg1.fn(arg2, arg3, ...)

因此,只有当函数的结果可以作为第一个参数传递给下一个函数时,这种技术才有效。在DuckDB中,大多数函数的签名使这成为可能。

如果我们要重写上面的查询来使用链式调用,我们可以相当容易地做到这一点:

FROM (SELECT range(1,50,5).unnest() AS num)
SELECT
  num,
  CAST(num.sqrt().power(3).log2() AS INTEGER).factorial() AS val;

返回结果:

num|val               |
---+------------------+
  1|               0.0|
  6| 3.877443751081734|
 11|5.1891474279559455|
 16|               6.0|
 21| 6.588476134168141|
 26| 7.050659577211638|
 31| 7.431294465580312|
 36| 7.754887502163468|
 41| 8.036328006927125|
 46|  8.28534293408552|

自定义转换函数

但是现在我们有点卡住了,因为我们不能链接CAST函数。我们可以像普通的那样编写CAST,然后调用factorial:

FROM (SELECT range(1,50,5).unnest() AS num)
SELECT
  num,
  CAST(num.sqrt().power(3).log2() AS INTEGER).factorial() AS val;

虽然解决了cast函数调用问题,但如果我们能把所有东西都锁起来,那还是很酷的。不幸的是,没有可以动态转换值的函数,这有点令人沮丧。但是我们可以做的是自己创建只用于转换为整数的函数:

CREATE OR REPLACE MACRO asInt(value) AS
  CAST(value AS INTEGER);

现在可以链接所有查询中函数:

FROM (SELECT range(1,50,5).unnest() AS num)
SELECT
  num,
  num.sqrt().power(3).log2().asInt().factorial() AS val;

查询结果:

num|val  |
---+-----+
  1|    1|
  6|   24|
 11|  120|
 16|  720|
 21| 5040|
 26| 5040|
 31| 5040|
 36|40320|
 41|40320|
 46|40320|

总结

是不是很酷,关于如何自定义函数(或宏),下次我们再分享。希望对你有用,一起学习。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值