【Hive SQL 每日一题】行列转换

news2024/11/14 19:51:42

文章目录

    • 行转列
    • 列传行

行转列

测试数据:

DROP TABLE IF EXISTS student_scores;

CREATE TABLE student_scores (
    student_id INT,
    subject STRING,
    score INT
);


INSERT INTO student_scores (student_id, subject, score) VALUES
(1, 'Math', 85),
(1, 'English', 78),
(1, 'Science', 92),
(2, 'Math', 88),
(2, 'English', 76),
(2, 'Science', 81),
(3, 'Math', 90),
(3, 'English', 82),
(3, 'Science', 89);

表的结构以及数据展示如下:

student_idsubjectscore
1Math85
1English78
1Science92
2Math88
2English76
2Science81
3Math90
3English82
3Science89

根据上面的学生成绩表,将其中的行转换成列进行展示,如下所示:

student_idmathenglishscience
1857892
2887681

这个需求主要从两个方面切入:

  • 因为是统计每名学生的成绩,所以按学生进行分组。

  • 行转列操作,其实就是将行数据通过列的方式进行查询展示而已,这里将行转为列的数据共有 3 列,分别代表每名同学各科的成绩,我们只需要在统计时加入判断条件即可,每列固定求某科的成绩,如果不是该科则用 0 或者空值替代,这样就可以轻松完成需求啦。

select
  student_id,
  sum(if(subject="Math",score,0)) math,
  sum(if(subject="English",score,0)) english,
  sum(if(subject="Science",score,0)) science
from
    student_scores
group by
    student_id;

输出结果如下:

在这里插入图片描述

列传行

现在变换一下需求,将学生成绩表中的数据列转换为行,测试数据:

DROP TABLE IF EXISTS student_scores_pivoted;
CREATE TABLE student_scores_pivoted (
    student_id INT,
    math INT,
    english INT,
    science INT
);

INSERT INTO student_scores_pivoted VALUES
(1, 85, 78, 92),
(2, 88, 76, 81),
(3, 90, 82, 89);

表的结构以及数据展示如下:

student_idMathEnglishScience
1857892
2887681
3908289

我们需要将其转换为如下结构:

student_idsubjectscore
1Math85
1English78
1Science92
2Math88
2English76
2Science81
3Math90
3English82
3Science89

这里使用到了 lateral view + posexplode 的方式,将表的一列扩展到多行,从而完成列转行的需求。

相较于传统的 lateral view + explode 扩展方式,posexplode 会返回两个参数,其中第一个参数表示索引,第二个参数才是其对应的值。

select
    student_id,
    subject_name_list,
    subject_list
from
    (select
        student_id,
        concat_ws(',',"Math","English","Science") subject_name,
        concat_ws(',',cast(math as string),cast(english as string),cast(science as string)) subject
    from
        student_scores_pivoted)t1 
    lateral view posexplode(split(subject,",")) tmp1 as pos1,subject_list
    lateral view posexplode(split(subject_name,",")) tmp2 as pos2,subject_name_list
where
    tmp1.pos1 = tmp2.pos2;

输出结果如下:

在这里插入图片描述

explodeposexplode 的区别:

-- explode 主要用于将一个包含多个元素的列转换为多行,每行对应一个元素。
SELECT explode(array(1, 2, 3));
-- 结果为:
1
2
3

-- posexplode 与 explode 类似,但它不仅返回数组中的值,还返回值在数组中的位置(索引)。
SELECT posexplode(array(1, 2, 3));
-- 结果为:
0  1
1  2
2  3

那么这里为什么使用 posexplode 而不是 explode 呢?

如果在这里使用 explode,那么会导致扩张多次(因为在这里使用了两次 explode3*3 最终会将每行扩张 9 次,形成笛卡尔积),变成如下所示的结果:

在这里插入图片描述

所以在这里并不使用 explode,推荐使用另一个函数 posexplode,虽然它也会导致笛卡尔积,但可以根据索引设置条件进行过滤:

在这里插入图片描述

下面将来讲述这些笛卡尔积数据产生的原因,以及过滤条件该如何设置。

在只使用一个扩展函数时,并不会产生笛卡尔积,如下所示:

在这里插入图片描述

如果同时使用两个扩展函数,那么就会产生笛卡尔积,会随着后续每行的数据量成倍数增长,如下所示:

在这里插入图片描述

在使用 posexplode 函数形成笛卡尔积后,我们可以通过设置 where 条件来进行过滤,取到对应的数据。

通过观察可以发现,只有当两个索引列的值相同时,其扩展的数据行才是正确的,我们可以通过这一特性来对数据进行过滤,获取最终的结果:

在这里插入图片描述

其实,列转行还有其它的写法,这里提供另一种更容易理解的思路:

  • 先通过子查询获取单科的成绩;

  • 然后再进行合并。

如下所示:

select
    student_id,
    "math" subject_name,
    math score
from
    student_scores_pivoted
union all
select
    student_id,
    "english" subject_name,
    english score
from
    student_scores_pivoted
union all
select
    student_id,
    "science" subject_name,
    science score
from
    student_scores_pivoted;

输出结果如下:

在这里插入图片描述

解决问题的方式有许多种,但往往我们需要去注重学习解决问题的思路,希望本文对你有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1701931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光纤跳线组成结构划分你知道吗

按照组成结构划分 光纤跳线根据组成结构的不同可分为带状光纤跳线和束状光纤跳线。带状光纤跳线使用的是由光纤带组成的带状光缆,大多呈扁平形状,因具有较高的光纤密度,它可以容纳更多的纤芯,因此大大节省布线成本和空间&#xf…

JavaScript 新特性:新增声明命令与解构赋值的强大功能

个人主页:学习前端的小z 个人专栏:JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结,欢迎大家在评论区交流讨论! ES5、ES6介绍 文章目录 💯声明命令 let、const🍟1 let声明符&a…

VMware虚拟机如何与主机共享文件夹

本机:WIN10 VMware虚拟机:WIN7 因为每次配置都爱忘记操作,目标是为了在WIN7虚拟机中可以访问本机文件 首先本机操作 新建一个共享文件夹,不带中文目录(最好不要) 点击共享 选择everyone,记得权限"读取和写入" 然后到虚拟机里面 添加一个网络位置 点击浏览,选择网…

刷题之从前序遍历与中序遍历序列构造二叉树(leetcode)

从前序遍历与中序遍历序列构造二叉树 前序遍历&#xff1a;中左右 中序遍历&#xff1a;左中右 前序遍历的第一个数必定为根节点&#xff0c;再到中序遍历中找到该数&#xff0c;数的左边是左子树&#xff0c;右边是右子树&#xff0c;进行递归即可。 #include<vector>…

ChatGPT-4o模型功能介绍——还没用过的看过来

1.概述 OpenAI 持续突破人工智能的边界&#xff0c;推出了其最新模型 ChatGPT-4o&#xff0c;作为 ChatGPT-4 的继承者&#xff0c;该模型有望带来显著的提升和创新功能。本文将深入解析 ChatGPT-4 与 ChatGPT-4o 之间的区别&#xff0c;并探讨它们的功能、性能以及潜在的应用…

5.22 R语言-正态性检验

正态性检验 正态性检验的目的是确定一组数据是否符合正态分布&#xff08;也称高斯分布&#xff09;。在统计分析和数据建模中&#xff0c;正态性假设是许多统计方法和模型的基础。了解数据是否符合正态分布有助于选择适当的统计方法和确保分析结果的有效性。 本文主要从概率…

神秘山洞惊现AI绘画至宝Stable Diffusion残卷

最近听到不少大宗门纷纷发声&#xff1a;随着AI神器的现世“程序员职业将不复存在”&#xff0c;“设计师将要失业”。 至此&#xff0c;不少修士开始担忧起来&#xff0c;现出世的AI神器会不会取代掉我辈修士。 其实&#xff0c;至女娲天神创造人类以来&#xff0c;在这漫漫…

RabbitMQ 交换机类型

常用交换机 发布订阅&#xff08;Publish/Subscribe&#xff09;交换机 一个生产者给多个队列发送消息&#xff0c;X 代表交换机。 交换机的作用&#xff1a;类似网络路由器&#xff0c;主要提供转发功能&#xff0c;解决怎么把消息转发到不同的队列中&#xff0c;让消费者从不…

基于Java+MySQL+Swing的学生管理系统

1.系统简介和开发背景 该同学工作积极主动、高效&#xff0c;学习认真&#xff0c;待人诚恳&#xff0c;能够做到服从指挥、认真听取老同志的指导&#xff0c;不怕苦、不怕累&#xff0c;表现有较强的求知欲&#xff0c;积极观察、体验、思考&#xff0c;并能够灵活运用自己的知…

Web安全技术期末考查-vulhub靶场搭建及漏洞复现

一、实验目的与要求 能根据报告找到难度适中的漏洞&#xff0c;搭建弱点环境&#xff0c;并验证该漏洞&#xff1b; 2.能给出该漏洞的修复建议。 二、实验原理与内容 漏洞原理 漏洞原理通常指的是计算机系统、软件、网络或其他技术系统中存在的安全缺陷&#xff0c;这些缺陷…

rapidssl泛域名https600元一年

泛域名https证书也可以称之为通配符https证书&#xff0c;指的是可以用一张https证书为多个网站(主域名以及主域名下的所有子域名网站)传输数据加密&#xff0c;并且提供身份认证服务的数字证书产品。RapidSSL旗下的泛域名https证书性价比高&#xff0c;申请速度快&#xff0c;…

浅谈JMeter体系结构

JMeter体系结构详解 JMeter是一款功能强大的开源性能测试工具&#xff0c;广泛应用于Web应用、数据库、FTP服务器等多种场景下的负载和压力测试。其灵活的体系结构设计使得测试计划的创建、执行与结果分析变得高效而直观。本文将深入解析JMeter的三维空间体系结构&#xff0c;…

SSE(Server Sent Event) 踩坑留念

整条链路是 客户端A --> 服务端 A —> 服务端 B 我负责服务端 A 此时要注意 Client 中的 processes 的写法 Post(value “/v2/xx”, processes MediaType.TEXT_EVENT_STREAM) 这样写是一直报错的 改成下面的写法才可以 Post(value “/v2/xx”, processes MediaT…

HTTP 协议的基本格式和Fidder的简单使用

HTTP协议诞生于1996&#xff08;开玩笑哈&#xff0c;诞生于1991年&#xff09;&#xff0c;http协议用于网页和手机app和服务器交互的场景。通过HTTP协议&#xff0c;客户端&#xff08;例如网页浏览器或手机应用&#xff09;可以向服务器发送请求&#xff0c;服务器则会响应这…

10个最佳人物素材网站推荐,免费获取第一个PNG文件!

人物素材是设计中应用最广泛的元素之一。无论是网页设计还是移动终端设计&#xff0c;人物素材的插画设计都比文字信息更容易吸引用户的注意力。作为内容呈现&#xff0c;还可以增加设计的艺术属性。为了节省大家寻找人物素材的时间成本&#xff0c;本文立即为大家整理了10个宝…

数据结构的直接插入排序(C语言版)

一.直接插入排序的基本概念 1.直接插入排序的基本思想 将数组分为已排序和未排序两部分。 每次从未排序部分取出一个元素,将其插入到已排序部分的合适位置,使得已排序部分保持有序。 重复步骤2,直到整个数组有序。 2.排序的工作原理 假设前 i-1 个元素已经有序,现在要将第…

【Django】开发个人博客系统【1】

使用Django开发个人博客系统&#xff0c;博客系统包括用户&#xff08;博主&#xff09;注册和登录、博主资料信息、图片墙功能、留言板功能、文章列表、文章正文内容和Admin后台系统。 1. 项目架构设计 下一步将上述设置写入Django的配置文件settings.py&#xff0c;当Django…

利用C#中WinForm设计一个小游戏:DoYouLoveMe???

目录 一、WinForm 二、功能实现 三、代码部分 一、WinForm Windows 窗体是用于生成 Windows 桌面应用的 UI 框架。 它提供了一种基于 Visual Studio 中提供的可视化设计器创建桌面应用的高效方法。 利用视觉对象控件的拖放放置等功能&#xff0c;可以轻松生成桌面应用。 使…

适合大学生低成本创业的又一个项目推荐(宿舍小卖部)

​ 大学生的时间是非常充裕的&#xff0c;这也导致了大学生非常的懒惰&#xff0c;每天除了娱乐&#xff08;打游戏&#xff0c;针对大部分人&#xff09;&#xff0c;也没有其它爱好了&#xff0c;就连吃饭都要抽时间来吃&#xff0c;所以这就给同学在宿舍做点小生意带来了机会…

如何在忘记密码的情况下解锁 iPhone? 6 种方法分享

您是否因为没有密码而无法解锁您的 iPhone&#xff1f; 别担心&#xff0c;这种情况比你想象的更常见&#xff01;忘记密码是 iPhone 用户面临的最常见问题之一&#xff0c;而且可能非常令人沮丧 - 但不要绝望。 在这篇文章中&#xff0c;我们将与您分享绕过 iPhone 屏幕密码…