热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL如何返回动态列数行列变换json,jsonb,record,temptable,tablefunc,pivottable,crosstab

digoal德哥专栏PostgreSQL如何返回动态列数-行列变换-json,jsonb,record,temptable,tablefunc,pivottabl

作者

digoal


日期

2020-12-26


标签

PostgreSQL , 动态列数 , json , jsonb , record , temp table , tablefunc , pivot table , crosstab , array




背景

在某些场景中, 可能希望sql返回动态列数, 例如BI报表系统. 一个查询的结果中可能包含的列数不定.

例如返回:

id,arr
1,{1,2}
2,{1,2,3,4}

又或者是其他更复杂的情况.

具体的方法比较多, 包括:

1、tablefunc插件, 行列变换, 里面支持自定义N type, 变换为N列.

《PostgreSQL Oracle 兼容性 - 行列变换(pivot unpivot) (tablefunc, crosstab)》

2、开篇的例子, 可以封装在函数中, 在函数内根据array长度定义返回的临时表, 最后通过查询这个临时表来返回. 例子

```

create or replace function dyn_out (int4[]) returns void as $$

declare

sql1 text := '';

sql2 text := '';

i int := 1;

x int;

begin

sql1 := 'create temp table if not exists temp1 (';

sql2 := 'insert into temp1 values (';

foreach x in array $1 loop

sql1 := sql1||'c'||i||' int ,';

sql2 := sql2||x||',';

i := i+1;

end loop;

sql1 := rtrim(sql1,',')||') on commit drop';

sql2 := rtrim(sql2,',')||')';

execute sql1;

execute sql2;

end;

$$ language plpgsql strict;

```

不支持采用CTE查询这个在函数中新建的临时表.

postgres=# with a as (select dyn_out(array[1,2,3,4])) select * from temp1;
ERROR: relation "temp1" does not exist
LINE 1: ...h a as (select dyn_out(array[1,2,3,4])) select * from temp1;
^

必须分为两次

```

postgres=# begin;

BEGIN

postgres=*# select dyn_out(array[1,2,3,4]);

dyn_out



(1 row)

postgres=*# select * from temp1;

c1 | c2 | c3 | c4

----+----+----+----

1 | 2 | 3 | 4

(1 row)

postgres=*# end;

COMMIT

```

3、如果BI系统仅支持一次调用, 可以考虑使用JSON类型作为返回值, 不管多少列, 都可以包含在一个JSON里面.

将结果封装在json内, 通过jsonb_populate_recordset或json_populate_recordset解析json:

```

postgres=# create type ints_4 as (a int, b int, c int, d int);

CREATE TYPE

postgres=# select * from jsonb_populate_recordset(null::ints_4, '[{"a":1,"b":2}, {"a":3,"b":4,"c":100,"d":200}]');

a | b | c | d

---+---+-----+-----

1 | 2 | |

3 | 4 | 100 | 200

(2 rows)

```

4、如果query能定义返回结构, 采用record返回类型的函数也能实现动态列.

create or replace function f(text) returns setof record as $$
declare
begin
return query execute $1;
end;
$$ language plpgsql strict;

```

select * from f($$select generate_series(1,10), random()*10, md5(random()::text), now()$$)

as t (id int, c1 float8, c2 text, c3 timestamptz);

id | c1 | c2 | c3

----+--------------------+----------------------------------+-------------------------------

1 | 1.2760291454197414 | 0f108bfc50b2a9b988128dd6c8ea4d9e | 2020-12-26 12:26:09.178573+08

2 | 9.820227323439639 | 551740c9ca1fe1db782f8695d8b4272e | 2020-12-26 12:26:09.178573+08

3 | 7.771695476696081 | bf284c1631865e58fd2ee23f2a2cb354 | 2020-12-26 12:26:09.178573+08

4 | 5.25456496894833 | 6373ade2ba1421eabfea89c42c0ce339 | 2020-12-26 12:26:09.178573+08

5 | 9.606696936766994 | 6a6fe86d124066425b5257093f4f0d86 | 2020-12-26 12:26:09.178573+08

6 | 2.7529741829887655 | e3ba7b4ac3b3d021013b617428f64d26 | 2020-12-26 12:26:09.178573+08

7 | 3.508055632020657 | 4c95a661968ee0bbf6248e4739d2183f | 2020-12-26 12:26:09.178573+08

8 | 3.2396315515742913 | f5602c9dffe52b58917ea73be30eb0a5 | 2020-12-26 12:26:09.178573+08

9 | 0.7574322479838003 | 58be0d9d0a5f1b18ecedf38303932885 | 2020-12-26 12:26:09.178573+08

10 | 7.912392299341349 | 2aab9f549d39d94e909189fb4a5ee62b | 2020-12-26 12:26:09.178573+08

(10 rows)

```


参考

《PostgreSQL Oracle 兼容性 - 行列变换(pivot unpivot) (tablefunc, crosstab)》

https://www.postgresql.org/docs/13/functions-json.html#FUNCTIONS-JSON-PROCESSING

https://www.postgresql.org/docs/13/tablefunc.html

https://www.postgresql.org/docs/13/plpgsql.html


PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.


9.9元购买3个月阿里云RDS PostgreSQL实例


PostgreSQL 解决方案集合


德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • Summarize function is doing alignment without timezone ?
    Hi.Imtryingtogetsummarizefrom00:00otfirstdayofthismonthametric, ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • Python 可视化 | Seaborn5 分钟入门 (六)——heatmap 热力图
    微信公众号:「Python读财」如有问题或建议,请公众号留言Seaborn是基于matplotlib的Python可视化库。它提供了一个高级界面来绘制有吸引力的统计图形。Seabo ... [详细]
  • 【技术分享】一个 ELF 蠕虫分析
    【技术分享】一个 ELF 蠕虫分析 ... [详细]
author-avatar
you是was的was
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有