[pgrx开发postgresql数据库扩展]7.返回序列的函数编写(2)表序列

news/2024/11/20 13:28:01/

前文再续,书接上一回。

上一节我们简单说了利用SetOfIterator返回一个srf(Set Returning Functions),但是很多情况下,一个单值序列并不能很好的满足我们的需求,所以今天我们来说另外一个作用更广泛的srf:

TableIterator

顾名思义,SetOfInterator返回的是一个Set,那么TableIterator返回的自然是一个表格了,下面先来看一个例子:

代码如下:(具体说明后面再说)

#[pg_extern]
fn get_values() -> 
TableIterator<'static, (name!(index, i32), name!(value, f64))> {let v:Vec<(i32,f64)> = vec![(1,0.5),(2,0.33),(3,0.15),(4,0.35)];TableIterator::new(v)
}

效果如下:

有同学说,虾神,你出来的这个内容,不是表格啊,每行怎么都是一个tuple呢?

别急,我们换一个写法:

对比一下我们的接口,就很明显了,我们在函数里面定义的返回类型,正好对应生成的表格中的字段,而TabletIterator里面的值,就正好对应了生成的表格里面的值:

下面我们来简单解析TabletIterator这个返回类型的代码:

/**
语法:
TableIterator<'生命周期标识, (name!(字段名1, 字段类型1), name!(字段名2, 字段类型2),name!(字段名n, 字段类型n),……)>
其中,name!是Rust的定义的宏,里面的参数一个是tuple,用于声明返回值的结构,尤其是返回值为表迭代器的函数中提供 SQL 名称。
*/
//示例:
TableIterator<'static,(name!(id, i64),name!(dept_code, String),name!(full_text, &'static str))

然后看看这个结构的构造方式:

//首先构造一个集合,集合内部的结构与定义的结构一样:
let v:Vec<(i32,f64)> = vec![(1,0.5),(2,0.33),(3,0.15),(4,0.35)];
//然后把处理好的集合,直接构造为TableIterator结构即可。TableIterator::new(v)

下面我们在来看一个例子,比如按照你需要的数量,来生成一个随机填充的表格,代码如下:

#[pg_extern]
fn random_values(num_rows: i32) -> 
TableIterator<'static, (name!(index, i32), name!(value, f64))> {TableIterator::new((1..=num_rows).map(|i| (i, rand::random::<f64>())))
}

效果如下:

使用SQL的方式来生成表格:

这个表格是可以完整使用SQL进行计算分析的,比如,生成100条随机数据,value大于0.95的,只有5条……很明显这个随机函数是正态分布的……:

好了,下面我们来看一个小案例:

返回一个序列的功能在实际工作中是经常用的,特别是做数据分析的同学,因为很多分析的结果不可能只有一条记录。

例如有些不追求数据库范式的设计,可能把数据存储成这个样子:

例如,其中values每天的平均空气质量(随机模拟数据,不要在意这些细节)

然后需求就是要对数组型字段进行计算……

当然,postgresql在9.6之后就支持json和array了,例如array可以通过ANY进行查询,也可以unnest函数进行展开:

例如我们要求2015年8月每个站点的最大值:

先要用UNNEST函数,把整个数组展开,然后再进行groupby。

但是现在问题来了,因为每个月的数据是按每天来计算的,我现在想知道,每个月,哪一天的数值最高?

要说找最高的,还是比较容易的,但是要找这是哪一天,就不太容易了,需要先求max,然后再求下标:

(叠甲:虾神对SQL不是特别熟,所以SQL代码写起来估计效率会很差,大家将就看看就是,不过:

效果如下:

那么我们如果要在pgrx里面来做这个功能,怎么做呢?相对来说就非常简单了,代码如下:

#[pg_extern]
fn get_max_value(value:Vec<i32>) ->
TableIterator<'static, (name!(day,i32),name!(maxvalue,i32))
>{let mut idx = 0;let mut max = 0;//求max的值和数组的下标for i in 0..value.len(){if max < value[i]{max = value[i];idx = i;}}//下标+1是因为pg的数组是从1开始的,另外我们求的是日期,也是从1开始TableIterator::new(vec![(idx as i32 + 1,max)])
}

效果如下:

用表格数据测试一下:

真是太残暴了……

打完收工


http://www.ppmy.cn/news/63436.html

相关文章

《光电容积法在评估高血压中的应用》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一课…

用CTGAN生成真实世界的表格数据

随着CLIP和稳定模型的快速发展&#xff0c;图像生成领域中GAN已经不常见了&#xff0c;但是在表格数据中GAN还是可以看到它的身影。 现实世界的复杂性与许多方面相关(例如&#xff0c;缺失数据、不平衡数据、噪声数据)&#xff0c;但最常见的一个问题是包含异构(或“混合”)数…

java中Math函数的用法

package com.test.test03;public class Test01 {//这是一个main方法&#xff0c;是程序的入口public static void main(String[] args) {//常用属性System.out.println(Math.PI);//常用方法System.out.println("随机数&#xff1a;"Math.random());System.out.printl…

Variable used in lambda expression should be final or effectively final

场景描述 我们在使用Java8 lambda表达式的时候时不时会遇到这样的编译报错&#xff1a; 这句话的意思是&#xff0c;lambda 表达式中使用的变量应该是 final 或者有效的 final&#xff0c;为什么会有这种规定&#xff1f; 匿名类中的局部变量 其实在 Java 8 之前&#xff0…

《面试1v1》动态代理

我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a; 那你能说一下反射和动态代理的关系吗&#xff1f; 候选人&#xff1a; 当然可以。动态代理是一种基于反射的机制&#xff0c;它可以在运行时动…

两个form表单的数据存入同一个数据库表,使用使用json操作

项目场景&#xff1a; 两个form表单的数据存入同一个数据库表 问题描述 1.两个from表单数据一起传到后端但是数据解析和xml文件的sql获取不到报错 2.数据接受到了但是提示数据类型不兼容 3.使用RequestBody注解报错Content type application/x-www-form-urlencoded;charsetUT…

【C++入门】引用

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

MGV2000_2+16_当贝纯净桌面卡刷固件包-内有教程

MGV2000_216_当贝纯净桌面卡刷固件包-内有教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软件&#xff0c;运行速度提…