greenplum行转列

这篇具有很好参考价值的文章主要介绍了greenplum行转列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

项目中需要将150w的数据转为1500列的大宽表数据。
最开始尝试了网上提供的两种方法:

SELECT 'Tim' name, '数学' subject, 'A' grade
UNION
SELECT 'Tim' name, '英语' subject, 'B' grade
UNION
SELECT 'Tim' name, '语文' subject, null grade
UNION
SELECT 'Tom' name, '数学' subject, 'B' grade
UNION
SELECT 'Tom' name, '英语' subject, 'D' grade
UNION
SELECT 'Tom' name, '语文' subject, 'B' grade

max + case when

实际业务中10行*1500列数据查询并插入需要25秒左右(测试服务器性能比较差)

-- insert into ....
select name,
	max(case subject when '数学' then grade end) 数学,
	max(case subject when '英语' then grade end) 英语,
	max(case subject when '语文' then grade end) 语文
FROM (
    SELECT 'Tim' name, '数学' subject, 'A' grade
    UNION
    SELECT 'Tim' name, '英语' subject, 'B' grade
    UNION
    SELECT 'Tim' name, '语文' subject, null grade
    UNION
    SELECT 'Tom' name, '数学' subject, 'B' grade
    UNION
    SELECT 'Tom' name, '英语' subject, 'D' grade
    UNION
    SELECT 'Tom' name, '语文' subject, 'B' grade
) t
GROUP BY t.name

case when的问题是每个case when的语句都会把分组后的数据判断一下,时间复杂度为O²(O为行转列后的列数),非常的慢。case when中注意源数据中不需要计算的数据一定要过滤掉,否则时间会更长(业务系统中忘记过滤数据导致时间膨胀了一倍多)。

tablefunc插件

实际业务中10行*1500列数据只查询需要7-8秒左右(测试服务器性能比较差)

select * from crosstab('select * from(
    SELECT ''Tim'' name, ''数学'' subject, ''A'' grade
    UNION
    SELECT ''Tim'' name, ''英语'' subject, ''B'' grade
    UNION
    SELECT ''Tim'' name, ''语文'' subject, null grade
    UNION
    SELECT ''Tom'' name, ''数学'' subject, ''B'' grade
    UNION
    SELECT ''Tom'' name, ''英语'' subject, ''D'' grade
    UNION
    SELECT ''Tom'' name, ''语文'' subject, ''B'' grade
) t order by name','select unnest( array[''数学'', ''语文'', ''英语'']) ')
AS sales_pivot(name varchar,数学 varchar,英语 varchar,语文 varchar)

crosstab的底层原理不知道是什么,但是不支持直接直接插入只能查询,直接插入不支持分布式运算。如果想配合insert直接插入,查询的数据表必须是复制表,这就需要把需要计算的数据复制到一张DISTRIBUTED REPLICATED的表中才可以。这样就会导致数据都是在一个节点上计算的,greenplum的分布式优势就没有了,同时复制数据也需要消耗时间。也可以把数据查出来再插入到数据库,需要一次服务器和数据库的数据流转。

array_agg

上面的方法都有弊端,官方资料中也没有相关的资料。有一天突然灵光一闪发现可以使用数组的方式,因为数组的定位效率高,性能会提升很多。

实际业务中10行*1500列数据查询并插入需要3秒左右(测试服务器性能比较差)

-- insert into ....
select t.name,t.grades[1] 数学,t.grades[2] 英语,t.grades[3] 语文 from(
	SELECT
	    t.name,
	    array_agg(t.grade order by t.subject) grades
	FROM (
	    SELECT 'Tim' name, '数学' subject, 'A' grade
	    UNION
	    SELECT 'Tim' name, '英语' subject, 'B' grade
	    UNION
	    SELECT 'Tim' name, '语文' subject, null grade
	    UNION
	    SELECT 'Tom' name, '数学' subject, 'B' grade
	    UNION
	    SELECT 'Tom' name, '英语' subject, 'D' grade
	    UNION
	    SELECT 'Tom' name, '语文' subject, 'B' grade
	) t
	GROUP BY t.name
)t;

array_agg的原理是把分组后的数据转换为数组,然后在使用数组的地址取出数据,时间复杂度为O。这种方法需要注意的是需要对列进行排序,转换的时候注意列的顺序。
同理也可以使用split_part+string_agg操作,但是split_part需要切割字符串效率并不会比array_agg高。文章来源地址https://www.toymoban.com/news/detail-773921.html

到了这里,关于greenplum行转列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • sql 行转列

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 实现行转列的两种方式,case when 与piovt 函数的使用例子与比对 示例:如需要将左边的表格转换成右边的表格 首先,根据资产属性先将数据分成四列 代码如下:` 结果如下: I 这样看起来比较乱,需要根

    2024年02月09日
    浏览(39)
  • PostgreSQL如何行转列

    PostgreSQL如何行转列 方法一: group by + sum + case when 方法二: 用postgresql的crosstab交叉函数 方法三: group by + string_agg + split_part(分组,行转列,字符切割) group by + string_agg

    2024年02月11日
    浏览(50)
  • mysql 行转列

    以下是其中比较常见的几种方法: 使用GROUP_CONCAT函数 可以使用GROUP_CONCAT函数将多行数据合并为一行,并以逗号或其他分隔符进行分隔。通过SELECT语句和GROUP BY子句,可以将数据行转换为列。具体语法如下: 其中,id表示非透视列,status表示需要转换为列的字段,value表示需要

    2024年02月16日
    浏览(51)
  • SqlServer行转列方法

    数据库建表 1 使用聚合函数巧妙解决,可以用max、sum等 2 使用pivot函数 3.行转列,多列,参考

    2024年02月15日
    浏览(66)
  • Mysql行转列函数

    group_concat() 例: select oid from Test;  select group_concat( oid ) from Test;

    2024年02月14日
    浏览(39)
  • spark sql如何行转列

    在数据仓库中,行转列通常称为”变形”(Pivoting) 或 “透视”(Pivoting),可使用Spark SQL的 pivot 语句实现。下面是一个简单的示例: 假设我们有如下表格: 我们想要把该表中的品牌列转换为4列,分别表示不同的品牌,而值则为对应品牌的年份。具体操作如下: 运行上面的代码

    2024年02月07日
    浏览(44)
  • Oracle——行转列与列转行

    把某一个字段的值作为唯一值,然后另外一个字段的 行值转换成它的列值 。 转换过程大致如下所示: 通常情况下,采取 group by 唯一字段 进行分组,然后依据不同的列进行判断输出就能转换。 建表语句和增加测试数据sql如下所示: 执行完毕后,数据库中当前的数据结构如

    2024年02月15日
    浏览(59)
  • 5分钟搞懂MySQL - 行转列

    小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL专栏目录 | 点击这里   MySQL 行转列 ,对经常处理数据的同学们来说,一定是不陌生的,甚至是印象深刻,因为它大概率困扰过你,让你为之一愣~ 但当你看到本文后,这个问题就不在是问题,及时收藏,以后谁再问你这个问

    2023年04月08日
    浏览(54)
  • Oracle行转列函数,列转行函数

    Oracle 可以通过 PIVOT , UNPIVOT ,分解一行里面的值为多个列,及来合并多个列为一行。 PIVOT 是用于将行数据转换为列数据的查询操作(类似 数据透视表 )。通过使用PIVOT,您可以按照特定的列值将数据进行汇总,并将其转换为新的列。 语法 pivot( 聚合函数 for 需要转为列的字段名

    2024年01月20日
    浏览(47)
  • Python操作Excel实战:Excel行转列

    # 1、原始数据准备 样例数据准备 地区 1m ³ 2-5m³ 6-10m³ 11-20m³ 21-40m³ 地区 单价 计费单位 费用最小值 费用最大值 北京 130 120 110 100 90 天津 130 120 110 100 90 石家庄 130 120 110 100 90 保定 140 130 120 110 100 张家口 170 150 130 120 110 邢台 140 120 110 100 90 邯郸 140 130 120 110 100 衡水 140 130 120 1

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包