Duckdb rusty_sheet插件使用心得

1.将rusty_sheet插件用于其他版本

rusty_sheet新版插件只能用于DuckDB 1.4.1版,如果需要用于其他版本,需要对插件中的版本号字符串替换。可以用这个python脚本替换1.4.1版本中的字符串。

步骤如下

(1)在duckdb 1.4.1版中查到插件安装位置

用select install_path from duckdb_extensions() where install_path like '%rusty_sheet%';查询位置

(2)退出duckdb ,复制到别处

copy 位置 tmp

(3)用python脚本替换

(4)用-unsigned加载替换后的版本

duckdb132 -unsigned -cmd "load 'tmp\rusty_sheet.duckdb_extension' "

就可以在1.3.2版中使用新版的功能,比如访问网络文件。

from read_sheet('https://www.miit.gov.cn/cms_files/filemanager/1226211233/attach/20259/795cf87158b0441ea697899f4cf626c4.xlsx') limit 4;

2.让rusty_sheet支持可变参数。

比如我有一个表列出了xlsx文件的清单,需要从清单中选择某个文件,因为duckdb不支持表函数用其他查询的结果做参数,过去的方法是先生成一个SQL脚本,再查询。

但表函数利用duckdb的set variable功能,可以变相地实现可变参数。

sql 复制代码
-- 假定有2个xlsx文件
D load excel;
D copy (select 1 a) to '1a.xlsx' (header 1);
D copy (select 2 b) to '2b.xlsx' (header 1);
-- 把它们的文件名和描述存在表中
D create table t as(select '1a.xlsx' f,'abc' d union select '2b.xlsx' ,'xyz');
-- 按描述查询文件名
D set variable n=(select f from t where d ='xyz');
D select getvariable('n');
┌──────────────────┐
│ getvariable('n') │
│     varchar      │
├──────────────────┤
│ 2b.xlsx          │
└──────────────────┘
-- 用变量n查询
D from read_sheet(getvariable('n'));
┌───────┐
│   b   │
│ int64 │
├───────┤
│   2   │
└───────┘
-- 如果返回超过1行
D set variable n=(select f from t);
Invalid Input Error:
More than one row returned by a subquery used as an expression - scalar subqueries can only return a single row.

Use "SET scalar_subquery_error_on_multiple_rows=false" to revert to previous behavior of returning a random row.
-- 用列表聚合
D set variable n=(select list(f) from t);
D select getvariable('n');
┌────────────────────┐
│  getvariable('n')  │
│     varchar[]      │
├────────────────────┤
│ [1a.xlsx, 2b.xlsx] │
└────────────────────┘
-- 用变量n查询2个文件
D from read_sheets(getvariable('n'));
┌───────┐
│   a   │
│ int64 │
├───────┤
│     1 │
│     2 │
└───────┘

3.配合miniplot插件画统计图

(1)安装miniplot插件

sql 复制代码
install miniplot from community;
load miniplot;

(2)查询xlsx文件

sql 复制代码
D from read_sheets(['stocks_data.xlsx']) limit 2;
┌──────────┬─────────────────────┬────────┬────────┬────────┬────────┬──────────┬────────┬───────────┬────────────┬─────────────┬───────────┐
│ 股票代码 │        时间         │ 开盘价 │ 最高价 │ 最低价 │ 收盘价 │ 前收盘价 │ 涨跌额 │ 涨跌幅(%) │ 成交量(股) │ 成交额(元)  │ 换手率(%) │
│ varchar  │      timestamp      │ double │ double │ double │ double │  double  │ double │  double   │   int64    │   double    │  double   │
├──────────┼─────────────────────┼────────┼────────┼────────┼────────┼──────────┼────────┼───────────┼────────────┼─────────────┼───────────┤
│ STK00267 │ 2024-01-01 09:30:46 │  98.45 │ 104.57 │  92.74 │ 102.98 │    98.83 │   4.15 │       4.2 │    2182810 │ 224785773.8 │      8.67 │
│ STK00417 │ 2024-01-01 09:30:47 │  14.52 │  15.37 │  13.55 │   14.8 │    15.25 │  -0.45 │     -2.95 │    5055707 │  74824463.6 │      7.98 │
└──────────┴─────────────────────┴────────┴────────┴────────┴────────┴──────────┴────────┴───────────┴────────────┴─────────────┴───────────┘
D select 股票代码,"涨跌幅(%)" from read_sheets(['stocks_data.xlsx']) order by "涨跌幅(%)" desc limit 5;
┌──────────┬───────────┐
│ 股票代码 │ 涨跌幅(%) │
│ varchar  │  double   │
├──────────┼───────────┤
│ STK01000 │     14.65 │
│ STK00877 │     14.45 │
│ STK00266 │     13.57 │
│ STK00875 │     13.34 │
│ STK00428 │      12.8 │
└──────────┴───────────┘
D select bar_chart(list(股票代码),list("涨跌幅(%)"),'涨幅前五') from (select 股票代码,"涨跌幅(%)" from read_sheets(['stocks_data.xlsx']) order by "涨跌幅(%)" desc limit 5);
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│               bar_chart(list("股票代码"), list("涨跌幅(%)"), '涨幅前五')                │
│                                         varchar                                         │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│ C:\Users\lt\AppData\Local\Temp\duckdb_chart_b31dd0960259aef6eaf45c713731aa93_80624.html │
└─────────────────────────────────────────────────────────────────────────────────────────┘ 

就会在输出的结果给出的路径保存网页,同时在浏览器打开。注意%不是合法的列名字符,需要用双引号括起来。

4.利用xlsx文件保存lua源代码,用read_sheet读出后由lua插件执行

lua函数中难以输入多行代码,比如如下代码

复制代码
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result;
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))

可以用xlsx文件的单元格来存储带换行符的字符串。

因为lua函数需要一个返回值,就在末尾添加一行return 1,然后复制粘贴到一个单元格的输入框中保存。注意在最开头输入一个单引号表示单元格是字符串。然后就可以用如下SQL执行这段代码。

list模式可以显示换行。

sql 复制代码
D .mode list
D from read_sheet('demo.xlsx',header=0);
A
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result;
end
-- 调用函数
print("两值比较最大值为 ",max(10,4))
print("两值比较最大值为 ",max(5,6))
return 1

.mode duckbox
D select lua(A) from read_sheet('demo.xlsx',header=0);
两值比较最大值为 	10
两值比较最大值为 	6
┌─────────┐
│ lua(A)  │
│ varchar │
├─────────┤
│ 1       │
└─────────┘

更实用的代码如下,利用context变量传入参数,参数可以是字面值,也可以是表中的数据

sql 复制代码
--[[ 函数返回两个值的最大值 --]]
function max(num1, num2)

   if (num1 > num2) then
      result = num1;
   else
      result = num2;
   end

   return result;
end
-- 调用函数
s=context
return max(s[1],s[2])

D select lua(A,[1,2]) from read_sheet('demo.xlsx',header=0);
┌───────────────────────────────┐
│ lua(A, main.list_value(1, 2)) │
│             json              │
├───────────────────────────────┤
│ 2                             │
└───────────────────────────────┘


D create table t as select 100 a,239 b;

D select lua(f.A,[t.a,b]) from read_sheet('demo.xlsx',header=0)f,t;
┌───────────────────────────────────┐
│ lua(f.A, main.list_value(t.a, b)) │
│               json                │
├───────────────────────────────────┤
│ 239                               │
└───────────────────────────────────┘

把xlsx文件作为保存自定义函数的库,在一定程度上可以弥补duckdb没有自定义函数的缺憾。

相关推荐
松涛和鸣43 分钟前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa1 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k1 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦2 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL3 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·3 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
野生技术架构师3 小时前
SQL语句性能优化分析及解决方案
android·sql·性能优化
IT邦德3 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫3 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写