DuckDB 宏的两种用法

参考文档
1.把值当做参数,用变量传入宏
下面的宏第一个参数是字符串,第二个参数是字符串列表

set variable va='ggrubuwrwuwbwwbwuuubuggggwwgurbwwubrbbgrurgbbwu';

set variable vb=['grbuu','bbg','rwrwrru','bw','bubrwg','rubrbg','ggubr','uw'];

CREATE or replace MACRO decom2(col1_value, col2_value) AS TABLE
with recursive test as (select col1_value a, col2_value b) --(select 'bike' a, ['bi', 'l','ike']b)-- 
, n as(select length(a) n from test)
, maxlen as(select array_aggr([len(word) for word in b], 'max') maxlen from test)
, test2 as(select col1_value a, list(b order by lenb) b from (select length(b)lenb,list(b) b from unnest(col2_value)b(b) group by length(b)))
, dp as(select repeat([0::bigint], n)dp from n)
, t using key(a)as(
    select True l,a,a a1,b, 1 i, dp from dp,test2
    union
    (with recursive d using key(i) as( 
      select l lo,a,a1,b,i, 1 le, dp d from t
      union
      select a[i-le+1:i] in b[le] and i-(le) =0,a,a[i-le+1:i],b,i, le+1, d[1:i-1]||
                 [case when a[i-le+1:i] in b[le] then d[i]+case when i-(le) >0 then d[i-(le)] else 1 end else d[i] end]
               ||d[i+1:] from  n, maxlen,d where le<=least(i, maxlen)
      )
    select lo,a,a1,b,d.i+1 lv, d from d  where d.i<=length(a) --and le=d.i+1
    )
)
select a,dp[length(a)]from t where i=length(a)+1;
--select i,a,b,a1,dp from t;

select * from decom2(getvariable('va') , getvariable('vb'));

┌─────────────────────────────────────────────────┬───────────────┐
│                        a                        │ dp[length(a)] │
│                     varchar                     │     int64     │
├─────────────────────────────────────────────────┼───────────────┤
│ ggrubuwrwuwbwwbwuuubuggggwwgurbwwubrbbgrurgbbwu │    1801368315 │
└─────────────────────────────────────────────────┴───────────────┘
Run Time (s): real 0.389 user 0.864000 sys 0.548000

2.把表名当做参数传入宏
这个表名既可以是物理表,也可以是CTE中的虚拟表,用query_table函数转换,下面宏的两个参数都是表名

CREATE or replace MACRO decom4(col1_value, col2_value) AS TABLE
with recursive  
test2 as(select a,b from query_table(col1_value),
            (select list(b order by lenb) b from
                (select length(b)lenb,list(b) b from query_table(col2_value) group by length(b))
          ))
, n as(select length(a) n from test2)
, maxlen as(select array_aggr([len(word) for word in b], 'max') maxlen from test2)

, dp as(select repeat([0::bigint], n)dp from n)
, t using key(a)as(
    select True l,a,a a1,b, 1 i, dp from dp,test2
    union
    (with recursive d using key(i) as( 
      select l lo,a,a1,b,i, 1 le, dp d from t
      union
      select a[i-le+1:i] in b[le] and i-(le) =0,a,a[i-le+1:i],b,i, le+1, d[1:i-1]||
                 [case when a[i-le+1:i] in b[le] then d[i]+case when i-(le) >0 then d[i-(le)] else 1 end else d[i] end]
               ||d[i+1:] from  n, maxlen,d where le<=least(i, maxlen)
      )
    select lo,a,a1,b,d.i+1 lv, d from d  where d.i<=length(a) --and le=d.i+1
    )
)
select a,dp[length(a)]from t where i=length(a)+1;


with recursive co as(
select trim(unnest(string_split(c, ',')))b from (from read_csv('2419-input01.txt', header=0, delim='-')t(c) limit 1)), 
w as(select a from read_csv('2419-input01.txt', header=0, delim='-', skip=2) t(a))
from decom4('w','co');

┌─────────┬───────────────┐
│    a    │ dp[length(a)] │
│ varchar │     int64     │
├─────────┼───────────────┤
│ bbrgwb  │             0 │
└─────────┴───────────────┘


上面查询中读取的数据文件2419-input01.txt的内容

r, wr, b, g, bwu, rb, gb, br

bbrgwb
<think>好的,我需要介绍如何在C++中使用DuckDB。首先,用户可能想知道DuckDB是什么,所以我要先简要说明它是一个嵌入式分析型数据库管理系统,适用于OLAP场景。接着,需要指导用户如何开始使用,比如安装和配置步骤。可能用户不熟悉如何获取DuckDB的C++库,所以得说明下载或编译的方法。 然后,需要给出一个简单的代码示例,展示如何连接数据库、创建表、插入数据和查询数据。这里要注意代码的正确性,比如包含正确的头文件,链接库文件,以及使用正确的命名空间。同时,要确保代码中的SQL语句正确,比如使用占位符和参数绑定来防止SQL注入。 接下来,用户可能对事务管理和错误处理感兴趣,所以需要解释DuckDB的事务支持,比如自动提交和显式事务,以及如何捕获异常。这部分需要强调异常处理的重要性,避免程序崩溃。 此外,性能优化也是关键点。需要提到DuckDB的列式存储、向量化查询执行和并行处理能力,以及如何通过预编译语句和批量数据插入来提高效率。这些内容帮助用户充分利用DuckDB的优势。 最后,总结DuckDB在C++中的适用场景,比如数据分析、机器学习预处理等,并指出其轻量级和无需独立服务器的优点。确保整个回答结构清晰,步骤明确,覆盖用户可能遇到的主要问题,同时保持语言简洁易懂。</think>C++ 中使用 DuckDB 的逐步指南: DuckDB 是一款轻量级嵌入式分析型数据库管理系统,专为 OLAP 场景设计。以下是在 C++ 项目中使用它的完整流程: 1. **环境准备** ```bash # 下载预编译库(Linux示例) wget https://github.com/duckdb/duckdb/releases/download/v1.0.0/duckdb_cli-linux-amd64.zip unzip duckdb_cli-linux-amd64.zip ``` 2. **基本使用示例** ```cpp #include "duckdb.hpp" using namespace duckdb; int main() { // 创建内存数据库 DuckDB db(nullptr); Connection con(db); // 创建表 con.Query("CREATE TABLE users(id INTEGER, name VARCHAR);"); // 插入数据(参数化查询) auto prep = con.Prepare("INSERT INTO users VALUES (?, ?)"); prep->Execute(1, "Alice"); prep->Execute(2, "Bob"); // 查询数据 auto result = con.Query("SELECT * FROM users"); result->Print(); return 0; } ``` 3. **核心功能说明** - **内存存储**:默认使用内存存储,适合快速分析 ```cpp DuckDB db(":memory:"); // 显式指定内存模式 ``` - **持久化存储** ```cpp DuckDB db("mydb.duckdb"); // 保存到文件 ``` 4. **高级特性** - **事务管理** ```cpp con.Query("BEGIN TRANSACTION"); try { con.Query("INSERT INTO users VALUES (3, 'Charlie')"); con.Query("COMMIT"); } catch (std::exception &e) { con.Query("ROLLBACK"); } ``` - **批量数据插入** ```cpp Appender appender(con, "users"); appender.BeginRow(); appender.Append<int32_t>(3); appender.Append<std::string>("Charlie"); appender.EndRow(); appender.Close(); ``` 5. **性能优化技巧** - 启用并行处理 ```cpp con.Query("PRAGMA threads=4"); ``` - 使用列式存储 ```cpp con.Query("CREATE TABLE sensor_data AS SELECT * FROM 'samples.csv'"); ``` **应用场景建议**: - 数据分析中间结果缓存 - 机器学习特征预处理 - 实时日志分析 - 嵌入式设备数据分析 **注意事项**: 1. 编译时需链接 `libduckdb.a` 2. 使用参数化查询防止 SQL 注入 3. 定期调用 `Checkpoint()` 保持数据持久化 4. 建议使用最新稳定版(当前 v1.0.0) 完整文档参考:https://duckdb.org/docs/api/cpp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值