【Databend】行列转化:一行变多行和简单分列

简介: 【Databend】行列转化:一行变多行和简单分列

数据准备和需求

行列转化在实际工作中很常见,其中最常见的有一行变多行,有下面一份数据:

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 生成序列有专门的函数 generate_series(, [, <step_interval>]),生成从指定点开始,在另一个指定点结束的数据集,并且可以选择增量值。适用的数据类型有 整数、日期和时间戳。

select generate_series as n  from generate(1, 10);
select generate_series as n  from generate(1, 10, 2);
+---+
| n |
+---+
| 1 |
+---+
| 3 |
+---+
| 5 |
+---+
| 7 |
+---+
| 9 |
+---+
select generate_series as n from generate_series('2024-01-01'::date, '2024-01-07'::date);
+---------------+
| calendar_date |
+---------------+
|   2024-01-01  |
+---------------+
|   2024-01-02  |
+---------------+
|   2024-01-03  |
+---------------+
|   2024-01-04  |
+---------------+
|   2024-01-05  |
+---------------+
|   2024-01-06  |
+---------------+
|   2024-01-07  |
+---------------+
  • split(<input_string>,):使用指定的分隔符拆分字符串,并将结果部分作为数组返回。
  • split_part(<input_string>,, ):使用指定的分隔符拆分字符串并返回指定的部分。
  • unnest(array):将数组拆分成多行。
select subject_level
     , split(subject_level, ',')         as split_char
     , split_part(subject_level, ',', 1) as part1
from (select 'china e,english d,math e' as subject_level) as a
+--------------------------+----------------------------------+------------+
|       subject_level      |             split_char           |   part1    | 
+--------------------------+----------------------------------+------------+
| china e,english d,math e | ['china e','english d','math e'] |  china e   |
+--------------------------+----------------------------------+------------+
select subject_level
     , unnest(split(subject_level, ',')) as unne_char
from (select 'china e,english d,math e' as subject_level) as a;
+--------------------------+------------+
|       subject_level      | unne_char  | 
+--------------------------+------------+
| china e,english d,math e |  china e   |
+--------------------------+------------+

split_part() 函数与 Mysql 中的 substring_index() 类似。

根据分隔符变多行

根据上面函数讲解,

方法一:我们可以使用 split(<input_string>,) 和 unnest(array) 函数实现。

select t1.student_id,t1.subject_level
,unnest(split(t1.subject_level,',')) as subject_level1
from fact_suject_data as t1
order by t1.student_id;

方法二:也可以使用 split_part(<input_string>,, ) 单独实现。

 select t1.student_id
     , t1.subject_level
     , t2.n
     , split_part(t1.subject_level, ',', t2.n) as subject_level1
from fact_suject_data as t1
         left join (select generate_series as n from generate_series(1, 30)) t2
                   on t2.n <= (length(t1.subject_level) - length(replace(t1.subject_level, ',', '')) + 1)
order by t1.student_id;

通过 generate_series() 生成的序列数值作为 split_part() 的分隔参数即可实现,与 Mysql 行列变换《你想要的都有》中分隔原理一致。

JSON 数据简单分列

对于 subject_level_json 列数据,我们可以使用 json 独有的函数实现分列透视的效果。

select subject_level_json
     , replace(json_path_query(subject_level_json, '$.china'), '"', '') as china
     , get(subject_level_json, 'math')                                  as math
     , get(subject_level_json, 'english')                               as english
from fact_suject_data as t1
order by t1.student_id;

总结

数据分列和一行变多行的应用非常常见,通过本文的学习,相信基本上能处理类似问题,遇到面试相关问题也能完美解决,赶紧动手实操看看效果吧!!!

参考资料:

https://blog.csdn.net/weixin_50357986/article/details/134161183

Databend 基础函数应用:https://blog.csdn.net/weixin_50357986/article/details/135535471

相关文章
|
7月前
|
C# 开发者
C# 7.0 中的元组:多值返回与结构化数据的便捷之道
【1月更文挑战第7天】C# 7.0 引入了元组作为一等公民,为开发者提供了一种方便的方式来返回多个值和处理结构化数据。元组不仅使方法能够返回多个不同类型的值,还通过语义化的命名提高了代码的可读性和可维护性。本文将探讨C# 7.0中元组的概念、特性、用法以及它们如何提升编程效率和代码质量。
|
Python
dataframe添加一新列
dataframe添加一新列
1887 2
|
分布式计算 数据处理 MaxCompute
MaxCompute单字段拆分多行多列
数据导入MaxCompute后,需要把某个字段String类型(多键值(key-value )对 ) 拆分成多行,每行有都有key, value两列。比如“{k1:v1,k2:v2,k3:k4}” 拆成多行,每行两个值key,value 分别为k1,v1;k2,v2;k3;k4。
3979 0
|
7月前
|
存储 数据库 文件存储
实时数仓 Hologres产品使用合集之建表字符串默认都是bitmap索引,如果字符串的是高基数的,会不会有影响
实时数仓Hologres是阿里云推出的一款高性能、实时分析的数据库服务,专为大数据分析和复杂查询场景设计。使用Hologres,企业能够打破传统数据仓库的延迟瓶颈,实现数据到决策的无缝衔接,加速业务创新和响应速度。以下是Hologres产品的一些典型使用场景合集。
135 9
|
6月前
|
分布式计算 DataWorks 大数据
MaxCompute产品使用合集之查询优化中对使用concat函数拼接起来的分区字段进行查询时,能否进行分区剪枝
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
6月前
|
SQL 数据采集 DataWorks
DataWorks产品使用合集之如何把两列字符串拼接的数据各自拆分成多行并组合
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
65 0
|
6月前
|
SQL JSON 关系型数据库
【Databend】基础函数应用
【Databend】基础函数应用
45 1
|
6月前
|
分布式计算 关系型数据库 数据挖掘
实时数仓 Hologres产品使用合集之如果采用组合主键,比如id + 时间时间(字符串),做为组合主键后是否会导致数据倾斜呢
实时数仓Hologres的基本概念和特点:1.一站式实时数仓引擎:Hologres集成了数据仓库、在线分析处理(OLAP)和在线服务(Serving)能力于一体,适合实时数据分析和决策支持场景。2.兼容PostgreSQL协议:Hologres支持标准SQL(兼容PostgreSQL协议和语法),使得迁移和集成变得简单。3.海量数据处理能力:能够处理PB级数据的多维分析和即席查询,支持高并发低延迟查询。4.实时性:支持数据的实时写入、实时更新和实时分析,满足对数据新鲜度要求高的业务场景。5.与大数据生态集成:与MaxCompute、Flink、DataWorks等阿里云产品深度融合,提供离在线
|
7月前
2352.相等行列对
2352.相等行列对
36 0
|
7月前
|
数据可视化 数据格式 索引
lindorm时序数据引擎可否将查询结果导成excel格式?
lindorm时序数据引擎可否将查询结果导成excel格式?
78 0