详情页标题前

阿里云云原生大数据计算服务 MaxCompute行转列及列转行最佳实践-云淘科技

详情页1

在数据开发、分析的过程中,您可能需要在不同维度下展示数据或为了符合某些数据表格式要求,此时需要对数据行转列列转行。本文以一个具体示例为您介绍在MaxCompute中实现行转列、列转行的SQL

背景信息

行转列与列转行的示意图如下。阿里云云原生大数据计算服务 MaxCompute行转列及列转行最佳实践-云淘科技

  • 行转列

    将多行数据转换成一行显示,或将一列数据转换成多列显示。

  • 列转行

    将一行数据转换成多行显示,或将多列数据转换成一列显示。

示例数据

为便于理解后续代码示例,本文为您提供源数据,并基于源数据提供相关转换示例。

  • 创建用于实现行转列的源表并插入数据,命令示例如下。

    CREATE TABLE rowtocolumn (name string, subject string, result bigint);
    INSERT INTO TABLE rowtocolumn VALUES 
    ('张三' , '语文' , 74),
    ('张三' , '数学' , 83),
    ('张三' , '物理' , 93),
    ('李四' , '语文' , 74),
    ('李四' , '数学' , 84),
    ('李四' , '物理' , 94);

    查询表rowtocolumn中的数据,命令示例如下:

    SELECT * FROM rowtocolumn;
    --返回结果。
    +------------+------------+------------+
    | name       | subject    | result     |
    +------------+------------+------------+
    | 张三        | 语文        | 74         |
    | 张三        | 数学        | 83         |
    | 张三        | 物理        | 93         |
    | 李四        | 语文        | 74         |
    | 李四        | 数学        | 84         |
    | 李四        | 物理        | 94         |
    +------------+------------+------------+
  • 创建用于实现列转行的源表并插入数据,命令示例如下。

    CREATE TABLE columntorow (name string, chinese bigint, mathematics bigint, physics bigint);
    INSERT INTO TABLE columntorow VALUES 
    ('张三' , 74, 83, 93),
    ('李四' , 74, 84, 94);

    查询表columntorow中的数据,命令示例如下:

    SELECT * FROM columntorow;
    --返回结果。
    +------------+------------+-------------+------------+
    | name       | chinese    | mathematics | physics    |
    +------------+------------+-------------+------------+
    | 张三        | 74         | 83          | 93         |
    | 李四        | 74         | 84          | 94         |
    | 张三        | 74         | 83          | 93         |
    | 李四        | 74         | 84          | 94         |
    +------------+------------+-------------+------------+

行转列示例

您可以通过如下两种方法实现行转列:

  • 方法一:使用case when表达式,灵活提取各科目(subject)的值作为单独的列,命令示例如下。

    SELECT name AS 姓名,
           max(case subject when '语文' then result end) AS 语文,
           max(case subject when '数学' then result end) AS 数学,
           max(case subject when '物理' then result end) AS 物理 
    FROM rowtocolumn 
    GROUP BY name;

    返回结果如下。

    +--------+------------+------------+------------+
    | 姓名   | 语文      | 数学     | 物理      |
    +--------+------------+------------+------------+
    | 张三   | 74       | 83       | 93        |
    | 李四   | 74       | 84       | 94        |
    +--------+------------+------------+------------+
  • 方法二:借助MaxCompute提供的内建函数实现,先基于CONCAT和WM_CONCAT函数合并科目和成绩为一列,然后通过KEYVALUE函数解析科目(subject)的值作为单独的列。命令示例如下。

    SELECT name AS 姓名,
           keyvalue(subject, '语文') AS 语文,
           keyvalue(subject, '数学') AS 数学,
           keyvalue(subject, '物理') AS 物理
    FROM(
         SELECT name, wm_concat(';',concat(subject,':',result))as subject 
         FROM rowtocolumn
         GROUP BY name);

    返回结果如下。

    +--------+------------+------------+------------+
    | 姓名   | 语文      | 数学      | 物理      |
    +--------+------------+------------+------------+
    | 张三   | 74       | 83        | 93        |
    | 李四   | 74       | 84        | 94        |
    +--------+------------+------------+------------+

说明

在实际业务开发过程中,如果您遇到行转列需求,还可以通过Lateral View、EXPLODE函数、INLINE函数以及TRANS_ARRAY函数将单行数据转为多行数据。

列转行示例

您可以通过如下两种方法实现列转行:

  • 方法一:使用union all,将各科目(chinese、mathematics、physics)整合为一列,命令示例如下。

    --解除order by必须带limit的限制,方便列转行SQL命令对结果按照姓名排序。
    SET odps.sql.validate.orderby.limit=false;
    --列转行SQL。
    SELECT name AS 姓名, subject AS 科目, result AS 成绩 
    FROM(
         SELECT name, '语文' AS subject, chinese AS result FROM columntorow 
         UNION all 
         SELECT name, '数学' AS subject, mathematics AS result FROM columntorow 
         UNION all 
         SELECT name, '物理' AS subject, physics AS result FROM columntorow) 
    ORDER BY name;

    返回结果如下。

    +--------+--------+------------+
    | 姓名   | 科目   | 成绩       |
    +--------+--------+------------+
    | 张三   | 语文   | 74         |
    | 张三   | 数学   | 83         |
    | 张三   | 物理   | 93         |
    | 李四   | 语文   | 74         |
    | 李四   | 数学   | 84         |
    | 李四   | 物理   | 94         |
    +--------+--------+------------+
  • 方法二:借助MaxCompute提供的内建函数实现,先基于CONCAT函数拼接各科目和成绩,然后基于TRANS_ARRAY和SPLIT_PART函数逐层拆解科目和成绩作为单独的列。命令示例如下。

    说明

    当您的待转换数据包含有NULL值时,使用此方式转换结果会不符合预期,因为CONCAT函数任一参数为NULL,返回结果就为NUL。您可以在使用方法二前先使用NVL函数,将NULL值转换为其他特殊值(例如0),NVL函数详情请参见NVL;或使用上述方法一进行转换。

    SELECT name AS 姓名,
           split_part(subject,':',1) AS 科目,
           split_part(subject,':',2) AS 成绩
    FROM(
           SELECT trans_array(1,';',name,subject) AS (name,subject) 
           FROM(
                SELECT name,
            concat('语文',':',chinese,';','数学',':',mathematics,';','物理',':',physics) AS subject 
                FROM columntorow)tt)tx;

    返回结果如下。

    +--------+--------+------------+
    | 姓名   | 科目   | 成绩       |
    +--------+--------+------------+
    | 张三   | 语文   | 74         |
    | 张三   | 数学   | 83         |
    | 张三   | 物理   | 93         |
    | 李四   | 语文   | 74         |
    | 李四   | 数学   | 84         |
    | 李四   | 物理   | 94         |
    +--------+--------+------------+

相关文档

您也可以通过PIVOT关键字实现行转换为列,通过UNPIVOT关键字实现列转换为行,请参见PIVOT、UNPIVOT。

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家

阿里云企业补贴进行中: 马上申请

腾讯云限时活动1折起,即将结束: 马上收藏

同尘科技为腾讯云授权服务中心。

购买腾讯云产品享受折上折,更有现金返利:同意关联,立享优惠

转转请注明出处:https://www.yunxiaoer.com/157251.html

(0)
上一篇 2023年12月10日 上午12:52
下一篇 2023年12月10日
详情页2

相关推荐

  • 阿里云RDS数据库使用SQL命令设置参数-云淘科技

    RDS SQL Server支持使用SQL命令或控制台设置参数,本文介绍如何使用SQL命令设置参数。 说明 本文适用于RDS SQL Server 2012及以上版本的实例。关于SQL Server 2008 R2的参数设置方法,请参见通过控制台设置参数。 支持设置的参数 fill factor (%) max worker threads cost thr…

    阿里云数据库 2023年12月9日
  • 阿里云RDS数据库数据迁移方案概览-云淘科技

    RDS提供了多种数据迁移方案,可满足不同上云或迁云的业务需求,使您可以在不影响业务的情况下平滑将数据库迁移至阿里云云数据库RDS上面。 通过使用阿里云数据传输服务(DTS),您可以实现SQL Server数据库的结构迁移和全量迁移。 下表列出了RDS支持的上云、迁云、数据导出场景以及相关的操作链接: 使用场景 相关操作 将本地数据库迁移到云数据库 SQL S…

    阿里云数据库 2023年12月9日
  • 数据传输DTS一条sql更新怎么会有两条dts的订阅消息?-云小二-阿里云

    数据传输DTS一条sql更新怎么会有两条dts的订阅消息146933246 146933274? 以下为热心网友提供的参考意见 源库是执行了update吗?update拆分成更新前和更新后两条值,且record_id是一样的 ,此回答整理自钉群“DTS客户交流群-2”

    2023年12月14日
  • Flink SQL中有没有行转列的函数东凌?-云小二-阿里云

    Flink SQL中有没有行转列的函数东凌 以下为热心网友提供的参考意见 在Flink SQL中,你可以使用内置的聚合函数GROUP_CONCAT来实现行转列的功能。这个函数会将输入数据按照指定的列进行分组,并将每个分组中的其他列的值拼接成一个字符串。例如,假设你有一个包含姓名和科目的表,并希望按姓名分组,同时将每个分组中的科目用逗号连接起来,可以使用如下查…

    阿里云 2024年1月4日
  • 信息流广告,信息流部分建议宽度830px,只针对默认列表样式,顺序随机
  • 有人用flink sql同步数据到oracle吗?-云小二-阿里云

    有人用flink sql同步数据到oracle吗? 以下为热心网友提供的参考意见 是的,有人使用Flink SQL同步数据到Oracle数据库。 Flink是一个开源流处理框架,可以用于实时数据处理和分析。Flink SQL是Flink提供的一种基于SQL语法的查询语言,可以方便地对流式数据进行查询和转换。 要将数据从Flink同步到Oracle数据库,可以…

    阿里云 2023年12月20日

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
本站为广大会员提供阿里云、腾讯云、华为云、百度云等一线大厂的购买,续费优惠,保证底价,买贵退差。