【Databend】行列转化:数据透视和逆透视

文章目录

数据准备

学生学科得分等级测试数据如下:

sql 复制代码
drop table if exists fact_suject_data;
create table if not exists fact_suject_data
(
    student_id    int          null comment '编号',
    subject_level varchar null comment '科目等级',
    subject_level_json variant null comment '科目等级json数据'
);
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (12,'china e,english d,math e','{"china": "e","english": "d","math": "e"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (2,'china b,english b','{"china": "b","english": "b"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (3,'english a,math c','{"english": "a","math": "c"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (4,'china c,math a','{"china": "c","math": "a"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (5,'china d,english a,math c','{"china": "d","english": "a","math": "c"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (6,'china c,english a,math d','{"china": "c","english": "a","math": "d"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (7,'china a,english e,math b','{"china": "a","english": "e","math": "b"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (8,'china d,english e,math e','{"china": "d","english": "e","math": "e"}');
insert into fact_suject_data(student_id, subject_level,subject_level_json) values (9,'china c,english e,math c','{"china": "c","english": "e","math": "c"}');

利用上一篇 【Databend】行列转化:一行变多行和简单分列 文章一行变多行,得到如下效果数据:

sql 复制代码
select t1.student_id
     , t1.subject_level
     , split_part(unnest(split(t1.subject_level, ',')), ' ', 1) as subject
     , split_part(unnest(split(t1.subject_level, ',')), ' ', 2) as level1
from fact_suject_data as t1
order by t1.student_id;

数据透视

Databend 中的 pivot 功能可以轻松实现数据透视,使用语法如下:

sql 复制代码
select ...
from ...
   pivot ( <aggregate_function> ( <pivot_column> )
            for <value_column> in ( <pivot_value_1> [ , <pivot_value_2> ... ] ) )
[ ... ]

参数解释如下:

  • <aggregate_function>:用于组合来自 <pivot_column> 的分组值的聚合函数。
  • <pivot_column>:将使用指定的 <aggregate_function> 聚合的列。
  • <value_column>:其唯一值将成为数据透视结果集中的新列。
  • <pivot_value_N>:来自<value_column>的唯一值,将成为透视结果集中的新列。
sql 复制代码
with a as
         (select t1.student_id
               , t1.subject_level
               , split_part(unnest(split(t1.subject_level, ',')), ' ', 1) as subject
               , split_part(unnest(split(t1.subject_level, ',')), ' ', 2) as level1
          from fact_suject_data as t1
          order by t1.student_id)
select *
from a pivot (max(level1) for subject in ('china','math','english'));

数据逆透视

Databend 中 unpivot 功能通过将列转换为行,起到数据逆透视效果。它是一个关系运算符,接受两列(来自表或子查询)以及列列表,并为列表中指定的每列生成一行。使用语法如下:

sql 复制代码
select ...
from ...
    unpivot ( <value_column>
    for <name_column> in ( <column_list> ) )
[ ... ]

参数解释:

  • <value_column>:将存储从<column_list>中列出的列中提取的值的列。
  • <name_column>:将存储提取值的列名称的列。
  • <column_list>:要旋转的列列表,用逗号分隔。

利用数据透视的结果,使用 unpivot 恢复原样实现数据逆透视。

sql 复制代码
with a as
         (select t1.student_id
               , t1.subject_level
               , split_part(unnest(split(t1.subject_level, ',')), ' ', 1) as subject
               , split_part(unnest(split(t1.subject_level, ',')), ' ', 2) as level1
          from fact_suject_data as t1
          order by t1.student_id),
     b as
         (select *
          from a pivot (max(level1) for subject in ('china','math','english')) )
select *
from b unpivot (level2 for subject in (`china`,`math`,`english`));

总结

Databend 的 pivot 和 unpivot 功能更好地实现数据的透视和逆透视,并且非常易读和分析大量数据,相较于 Mysql 实现数据透视 (case ...when...) 和逆透视 (union all) 来说更简单易读,方法不闲多主要是解决实际问题,学习了解更多方法和工具,在面对问题时也能更好的应对,赶紧实操起来,当遇到也能很自信地说"这题我会"。

参考资料:

相关推荐
曲幽2 小时前
FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
python·sql·postgresql·fastapi·web·postgres·db·asyncpg
DolphinDB8 小时前
集成 Prometheus 与 DolphinDB 规则引擎,构建敏捷监控解决方案
数据库
IvorySQL8 小时前
PostgreSQL 技术日报 (3月10日)|IIoT 性能瓶颈与内核优化新讨论
数据库·postgresql·开源
DBA小马哥12 小时前
时序数据库是什么?能源行业国产化替换的入门必看
数据库·时序数据库
爱可生开源社区14 小时前
某马来西亚游戏公司如何从 SQL Server 迁移至 OceanBase?
数据库
小瓦码J码16 小时前
PostgreSQL表名超长踩坑记
数据库·postgresql
yhyyht16 小时前
InfluxDB入门记录(三)flux-dsl
数据库·后端
IvorySQL1 天前
PostgreSQL 技术日报 (3月9日)|EXPLAIN ANALYZE 计时优化与复制语法讨论
数据库·postgresql·开源
用户8307196840821 天前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
stark张宇2 天前
MySQL 核心内幕:从索引原理、字段选型到日志机制与外键约束,一篇打通数据库任督二脉
数据库·mysql·架构