当前位置: 首页 > news >正文

利用DuckDB列表一句SQL输出乘法口诀表

先热身,用生成式列表输出几行不同长度的序列,从默认的标题列可知,生成式列表后台实际调用了list_apply函数。

D select [i for i in range(1,a+1)]from range(1,6)t(a);
┌─────────────────────────────────────────────────────┐
│ main.list_apply("range"(1, (a + 1)), (lambda i: i)) │
│                       int64[]                       │
├─────────────────────────────────────────────────────┤
│ [1]                                                 │
│ [1, 2]                                              │
│ [1, 2, 3]                                           │
│ [1, 2, 3, 4]                                        │
│ [1, 2, 3, 4, 5]                                     │
└─────────────────────────────────────────────────────┘

再把生成式的结果表达式变为字符串连接

D select [i::text||'*'||a::text||'='||(i*a)::text for i in range(1,a+1)]from range(1,6)t(a);
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ main.list_apply("range"(1, (a + 1)), (lambda i: ((((CAST(i AS VARCHAR) || '*') || CAST(a AS VARCHAR)) || '=') || C…  │
│                                                      varchar[]                                                       │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ['1*1=1']                                                                                                            │
│ ['1*2=2', '2*2=4']                                                                                                   │
│ ['1*3=3', '2*3=6', '3*3=9']                                                                                          │
│ ['1*4=4', '2*4=8', '3*4=12', '4*4=16']                                                                               │
│ ['1*5=5', '2*5=10', '3*5=15', '4*5=20', '5*5=25']                                                                    │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

其中的强制转换可以省略,DuckDB会自动转换

D select [i||'*'||a||'='||(i*a) for i in range(1,a+1)]from range(1,6)t(a);
┌───────────────────────────────────────────────────────────────────────────────────────────┐
│ main.list_apply("range"(1, (a + 1)), (lambda i: ((((i || '*') || a) || '=') || (i * a)))) │
│                                         varchar[]                                         │
├───────────────────────────────────────────────────────────────────────────────────────────┤
│ ['1*1=1']                                                                                 │
│ ['1*2=2', '2*2=4']                                                                        │
│ ['1*3=3', '2*3=6', '3*3=9']                                                               │
│ ['1*4=4', '2*4=8', '3*4=12', '4*4=16']                                                    │
│ ['1*5=5', '2*5=10', '3*5=15', '4*5=20', '5*5=25']                                         │
└───────────────────────────────────────────────────────────────────────────────────────────┘

字符串列表形式的输出不美观,可以转换为纯字符串。listagg函数直接嵌套unnest函数的方法不支持。

D select listagg(unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)])) from range(1,6)t(a);
Binder Error:
UNNEST not supported hereLINE 1: select listagg(unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)])) from...^

但是可以单独对列表unnest,就把列表中多个值转成多行

D select unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)]) from range(1,6)t(a);
┌───────────────────────────────────────────────────────────────────────────────────────────────────┐
│ unnest(main.list_apply("range"(1, (a + 1)), (lambda i: ((((i || '*') || a) || '=') || (i * a))))) │
│                                              varchar                                              │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 1*1=1                                                                                             │
│ 1*2=2                                                                                             │
│ 2*2=4                                                                                             │
│ 1*3=3                                                                                             │
│ 2*3=6                                                                                             │
│ 3*3=9                                                                                             │
│ 1*4=4                                                                                             │
│ 2*4=8                                                                                             │
│ 3*4=12                                                                                            │
│ 4*4=16                                                                                            │
│ 1*5=5                                                                                             │
│ 2*5=10                                                                                            │
│ 3*5=15                                                                                            │
│ 4*5=20                                                                                            │
│ 5*5=25                                                                                            │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│                                              15 rows                                              │
└───────────────────────────────────────────────────────────────────────────────────────────────────┘

还可以带上原来的列a

D select a,unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)]) from range(1,6)t(a);
┌───────┬───────────────────────────────────────────────────────────────────────────────────────────────────┐
│   a   │ unnest(main.list_apply("range"(1, (a + 1)), (lambda i: ((((i || '*') || a) || '=') || (i * a))))) │
│ int64 │                                              varchar                                              │
├───────┼───────────────────────────────────────────────────────────────────────────────────────────────────┤
│     11*1=1                                                                                             │
│     21*2=2                                                                                             │
│     22*2=4                                                                                             │
│     31*3=3                                                                                             │
│     32*3=6                                                                                             │
│     33*3=9                                                                                             │
│     41*4=4                                                                                             │
│     42*4=8                                                                                             │
│     43*4=12                                                                                            │
│     44*4=16                                                                                            │
│     51*5=5                                                                                             │
│     52*5=10                                                                                            │
│     53*5=15                                                                                            │
│     54*5=20                                                                                            │
│     55*5=25                                                                                            │
├───────┴───────────────────────────────────────────────────────────────────────────────────────────────────┤
│ 15 rows                                                                                         2 columns │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────┘

用listagg访问子查询就可以了,注意要针对列a排序

D select listagg(b,' ') from(select a,unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)])b from range(1,6)t(a))group by a;
┌───────────────────────────────────┐
│          listagg(b, ' ')          │
│              varchar              │
├───────────────────────────────────┤
│ 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 │
│ 1*1=1                             │
│ 1*4=4 2*4=8 3*4=12 4*4=16         │
│ 1*3=3 2*3=6 3*3=9                 │
│ 1*2=2 2*2=4                       │
└───────────────────────────────────┘
D select listagg(b,' ') from(select a,unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)])b from range(1,6)t(a))group by a order by a;
┌───────────────────────────────────┐
│          listagg(b, ' ')          │
│              varchar              │
├───────────────────────────────────┤
│ 1*1=1                             │
│ 1*2=2 2*2=4                       │
│ 1*3=3 2*3=6 3*3=9                 │
│ 1*4=4 2*4=8 3*4=12 4*4=16         │
│ 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 │
└───────────────────────────────────┘

上述输出随着数字变大,算式变长,没有对齐,可以用printf函数格式化,函数的格式符按照C语言的标准格式,-8表示8位宽左对齐,但注意格式符用单引号而不是双引号括起,双引号可以包括在单引号内原样输出。

D select listagg(printf('%-8s',b),' ') from(select a,unnest([i||'*'||a||'='||(i*a) for i in range(1,a+1)])b from range(1,6)t(a))group by a order by a;
┌──────────────────────────────────────────────┐
│       listagg(printf('%-8s', b), ' ')        │
│                   varchar                    │
├──────────────────────────────────────────────┤
│ 1*1=1                                        │
│ 1*2=2    2*2=4                               │
│ 1*3=3    2*3=6    3*3=9                      │
│ 1*4=4    2*4=8    3*4=12   4*4=16            │
│ 1*5=5    2*5=10   3*5=15   4*5=20   5*5=25   │
└──────────────────────────────────────────────┘D select printf('Benchmark "%s" took %d seconds', 'CSV', 42);
┌─────────────────────────────────────────────────────┐
│ printf('Benchmark "%s" took %d seconds', 'CSV', 42) │
│                       varchar                       │
├─────────────────────────────────────────────────────┤
│ Benchmark "CSV" took 42 seconds                     │
└─────────────────────────────────────────────────────┘

以下是结合递归CTE用行间列表运算输出杨辉三角

D with recursive t as(select 1 lv, [1]y union all select lv+1,[case when i=1 or i=lv+1 then 1 else y[i-1]+y[i] end for i in range(1, lv+2)] from t where lv <5 )from t;
┌───────┬─────────────────┐
│  lv   │        y        │
│ int32 │     int32[]     │
├───────┼─────────────────┤
│     1[1]             │
│     2[1, 1]          │
│     3[1, 2, 1]       │
│     4[1, 3, 3, 1]    │
│     5[1, 4, 6, 4, 1] │
└───────┴─────────────────┘
http://www.dtcms.com/a/618504.html

相关文章:

  • 兴宁网站设计凡客的官网
  • 大模型-Vllm 启用多模态数据-3
  • 集团网站建设定制网站建设中企动力是怎么建设网站的
  • Shell脚本猜数字,使用判断提示用户比目标数字是大还是小
  • 【开题答辩全过程】以 基于安卓的校园二手物品为例,包含答辩的问题和答案
  • 内测检测vs第三方软件检测的差异解析
  • 【科研绘图系列】R语言绘制多组条形图图(barplot)
  • Linux-线程
  • 最专业网站建设公备案域名是什么意思
  • SQL 约束
  • 创立一个网站要多少钱上海公司做网站的
  • MoE算法深度解析:从理论架构到行业实践
  • 【2025CVPR 异常检测方向】DFM: Differentiable Feature Matching for Anomaly Detection
  • 北京西站地铁是几号线做网站贵
  • 数据库第六次作业
  • 西宁大型网站建设网站如何做电脑和手机软件
  • 【Linux】Shell脚本
  • qt显示类控件---QProgressBar
  • 复式记账的“借”与“贷”
  • 设备健康管理诊断报告生成:工业智能化的“决策引擎”与效率革命​
  • 淘客网站是怎么做的成都网站排名生客seo怎么样
  • vscode插件开发记录
  • 做淘宝代理哪个网站好淘宝网店页面设计
  • 【Linux系统编程】进程控制
  • day2江协科技-3 GPIO
  • Photoshop文字设计基础知识
  • 自己做的网站项目怎样卖微信支付 企业网站
  • Java 大视界 -- Java 大数据机器学习模型在自然语言处理中的少样本学习与迁移学习融合
  • 全椒县城乡建设局网站centos。wordpress
  • 南京华夏商务网做网站怎么样腾讯qq网页版