首页 > 其他分享 >实例详解构建数仓中的行列转换

实例详解构建数仓中的行列转换

时间:2023-11-08 15:57:05浏览次数:34  
标签:数仓 score 实例 grade course 详解 -- SELECT name

本文分享自华为云社区《GaussDB数据库SQL系列-行列转换》,作者:Gauss松鼠会小助手2。

一、前言

在构建数据仓库或做数据分析时,需要对原始数据的结构进行一定的处理,有时涉及到“行转列”,有时涉及到“列转行”,那么这两个转换的方式具体是什么,有什么差异,怎么实现,今天我们将以GaussDB数据库为例,给大家做一下讲解。

二、简述

1、行转列概念

即将多行一列数据转为一行多列显示。通常转化后将某一列分类后的值作为新的列名,将此值对应的多行数据显示成一行。

cke_130.png

2、列转行概念

即将一行多列数据转成多行一列显示。通常将转化后的列名为某一行中某一列的值,来识别原先对应的数据。

cke_131.png

三、GaussDB数据库的行列转换实验示例

用一张学生成绩来举例:从老师的角度,在录入成绩时,每科老师都会单独录入每个学生的本科成绩。而从学生的角度,学生只关心自己各科的成绩分别是多少。所以如果把老师录入数据作为原始表,那么学生查看自己的成绩时就要用到行转列,如果让学生上报自己各科的成绩,然后老师去查对应学科的学生考试成绩时,那就是列转行了。

1、行转列示例

1)创建实验表(行存表)

--创建实验表(行存表)

CREATE TABLE grade(

name VARCHAR(10)

,course VARCHAR(10)

,score INT);

--初始化测试数据

INSERT INTO grade VALUES ('张三','数学',80);

INSERT INTO grade VALUES ('张三','英语',88);

INSERT INTO grade VALUES ('张三','语文',95);

INSERT INTO grade VALUES ('李四','数学',88);

INSERT INTO grade VALUES ('李四','英语',70);

INSERT INTO grade VALUES ('李四','语文',93);

--查看结果

SELECT * FROM grade ORDER BY course;

cke_132.png

2)静态行转列

--静态行转列

SELECT name

,sum(case when course = '数学' then score else 0 end) AS "数学"

,sum(case when course = '英语' then score else 0 end) AS 英语

,sum(case when course = '语文' then score else 0 end) AS 语文

FROM grade

GROUP BY name;

使用sum、case when的方式:

cke_133.png

3)行转列(结果值:拼接式)

使用listagg within group:

--行转列(结果值:拼接式)

SELECT name, LISTAGG(score,',') WITHIN GROUP (ORDER BY course) FROM grade GROUP BY name;

cke_134.png

4)动态行转列(拼接SQL式)

通过“listagg + 创建FUNCTION + VIEW”的方式实现

--动态行转列(SQL拼接式)

SELECT listagg(concat('SUM(CASE WHEN course = ''', course, ''' THEN score ELSE 0 END) AS "', course,'"'),',') WITHIN GROUP(ORDER BY 1) AS concat_text FROM (SELECT DISTINCT course FROM grade);

--concat_text的结果:

SUM(CASE WHEN course = '数学' THEN score ELSE 0 END) AS "数学",SUM(CASE WHEN course = '英语' THEN score ELSE 0 END) AS "英语",SUM(CASE WHEN course = '语文' THEN score ELSE 0 END) AS "语文"

--创建一个函数。

CREATE OR REPLACE FUNCTION fun_test()

RETURNS VOID

LANGUAGE SQL

AS $$ DECLARE

s_sql text;

rec record;

BEGIN

s_sql := 'SELECT listagg(CONCAT(''SUM(CASE WHEN course = '''''', course, '''''' THEN score ELSE 0 END) AS "'', course, ''"'' ),'','' ) WITHIN GROUP(ORDER BY 1) AS concat_text FROM (SELECT DISTINCT course FROM grade);';

EXECUTE s_sql INTO rec;

s_sql := 'DROP VIEW IF EXISTS v_score; CREATE VIEW v_score AS SELECT name, ' || rec.concat_text || ' FROM grade GROUP BY name;';

EXECUTE s_sql;

END $$;

--调用

CALL fun_test();

--查看执行结果

select * from v_score;

cke_135.png

Tip:请注意SQL拼写时的单引号、双引号。

2、列转行示例

1)创建实验表(复用前面的测试数据)

--创建实验表(复用前面的测试数据)

CREATE TABLE grade1 AS

SELECT name

,sum(case when course = '数学' then score else 0 end) AS "数学"

,sum(case when course = '英语' then score else 0 end) AS 英语

,sum(case when course = '语文' then score else 0 end) AS 语文

FROM grade

GROUP BY name;

--查看结果
SELECT * FROM grade1;

cke_136.png

2)使用union all,将各科目(数学、英语、语文)整合为一列

--使用union all,将各科目(数学、英语、语文)整合为一列

SELECT * FROM

(

SELECT name, '数学' AS course, 数学 AS score FROM grade1

union all

SELECT name, '英语' AS course, 英语 AS score FROM grade1

union all

SELECT name, '语文' AS course, 语文 AS score FROM grade1

)

order by name;

cke_137.png

四、小结

行列互转在一些数据库使用场景中经常用到,比如数据分析、数仓建设等。但不同的数据库软件有着不同处理方式,但是行列换的基本思路是一致的。本文主要是以GaussDB数据为平台,为大家做了简单的讲述 ,欢迎测试。

点击关注,第一时间了解华为云新鲜技术~

标签:数仓,score,实例,grade,course,详解,--,SELECT,name
From: https://www.cnblogs.com/huaweiyun/p/17817568.html

相关文章

  • 最全面的移动端UI组件设计详解:下篇
    上一期给大家讲解了《最全面的移动端UI组件设计详解:中篇》,主要分享了:基础组件、表单组件和反馈组件3个部分;这次给大家带来:数据展示组件和其他组件详解,希望你在设计APP、小程序、H5页面中,能熟练使用和理解各种的UI组件,今天给大家总结了关于移动端UI组件,希望可以在工作中帮到你。......
  • Spring 3.0 注解注入详解
    一、各种注解方式 1.@Autowired注解(不推荐使用,建议使用@Resource)     @Autowired可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作。@Autowired的标注位置不同,它们都会在Spring在初始化这个bean时,自动装配这个属性。要使@Autowired能够工作,还需要在配置文件中......
  • 最全面的移动端 UI组件设计详解:上篇
    作为一名UI设计师,我们经常要进行PC端和移动端的设计任务,上一次给大家分享了:《最全Web端UI组件设计详解》,这次给大家带来移动端UI组件设计详情,尤其在我们APP、小程序、H5页面设计中,我们要使用和熟知各种的UI组件,今天给大家总结了关于移动端UI组件,希望可以在工作中帮到你。什么......
  • OpenGL 摄像机视角详解
    1.摄像机摄像机就好像是我们的眼睛,我们从摄像机的方向观察世界空间中的模型。摄像机远离模型,模型自然就变小了(透视投影下),然而,在GL中事实上并没有摄像机的概念。但是我们可以通过移动世界空间远离我们的摄像机来模拟摄像机远离世界的感觉。这也正是在上一章中,我们的观察矩阵是(0,......
  • 每个构造函数都有个propotype属性,每个实例化对象都有个隐式原型__propo__,对象的隐式原
    每个构造函数都有个propotype属性,每个实例化对象都有个隐式原型__propo__,对象的隐式原型指向其构造函数的显示原型所有的引用类型(数组,对象,函数),都有__proto__属性,属性值是一个普通的对象对象分为函数对象和普通对象,只有函数对象是有prototype的,object.__proto__也有prototype,但它......
  • 数据类型详解
     注意:前边定义了后边输出就不用加引号,如果前边没有定义就后边加引号,如果加的是单引号就只能输入一个字符,如果是双引号就可以输入好多 ......
  • 30张图详解IP地址网络知识
    你们好,我的网工朋友。IP地址是所有网络初级课程里最先涉及到的技术点,对于IP地址的合理规划是网络设计的重要环节,必须拿捏。IP地址规划的好坏,影响到网络路由协议算法的效率,影响到网络的性能,影响到网络的扩展,影响到网络的管理,也必将直接影响到网络应用的进一步发展。今天和你分享一篇......
  • 数仓实践丨表扫描时过滤行数过多引起的性能瓶颈问题
    本文分享自华为云社区《GaussDB(DWS)性能调优:表扫描时过滤行数过多引起的性能瓶颈问题案例》,作者:O泡果奶~。1、【问题描述】SQL语句执行过程中,对12亿数据量的大表进行扫描,过滤99%的数据仅留617行数据,性能瓶颈位于扫描该表这里。2、【原始语句】setsearch_path='bi_dash......
  • 详解 Calico 三种模式(与 Fannel 网络对比学习)
    1.概述Calico是一个基于BGP的纯三层网络方案。它在每个计算节点都利用Linuxkernel实现了一个高效的虚拟路由器vRouter来进行数据转发。每个vRouter都通过BGP协议将本节点上运行容器的路由信息向整个Calico网络广播,并自动设置到达其他节点的路由转发规则。Calico保......
  • free -m 详解
    来源:https://blog.51cto.com/5250070/16609551.用途说明free命令用来显示内存使用状况。displayinformationaboutfreeandusedmemoryonthesystem。free命令相对于top提供了更简洁的查看系统内存使用状况:[root@localhost~]#free-mtotal......