PostgreSQL实现透视表查询

news2024/12/26 18:18:11

PostgreSQL 8.3版本发布时,引入了一个名为tablefunc的新扩展。这个扩展提供了一组非常有趣的函数。其中之一是交叉表函数,用于创建数据透视表。这就是我们将在本文中讨论的内容。
在这里插入图片描述

需求说明

解释此函数如何工作的最简单方法是使用带有数据透视表的示例。首先,我们将从实际角度解释我们最初的观点,然后定义所需的数据透视表。

假设我们是老师,需要统计你教所有科目的成绩(语言、音乐等),学校为你提供了记录所有评估或测试结果的系统。下面的SQL语句将显示之前加载到系统中的计算结果:

SELECT *
FROM evaluations

示例数据如下:

StudentSubjectEvaluation_resultEvaluation_day
Smith, JohnMusic7.02016-03-01
Smith, JohnMaths4.02016-03-01
Smith, JohnHistory9.02016-03-22
Smith, JohnLanguage7.02016-03-15
Smith, JohnGeography9.02016-03-04
Gabriel, PeterMusic2.02016-03-01
Gabriel, PeterMaths10.02016-03-01
Gabriel, PeterHistory7.02016-03-22
Gabriel, PeterLanguage4.02016-03-15
Gabriel, PeterGeography10.02016-03-04
  • 期望结果

下面的表格可以很容易地跟踪学生的进度。在计算机科学中,我们称这种网格为透视表。如果分析数据透视表,你会发现我们使用原始数据中的值作为列标题或字段名(在本例中是地理、历史、数学等)。

希望的数据格式如下:

StudentGeographyHistoryLanguageMathsMusic
Gabriel, Peter10.07.04.010.02.0
Smith, John9.09.07.04.07.0

启用tablefunc扩展

正如我们前面提到的,crosstab 函数是PostgreSQL扩展tablefunc的一部分。要调用crosstab 函数,必须首先通过执行以下SQL命令启用tablefunction扩展:

CREATE extension tablefunc;

crosstab 函数

crosstab 函数接收SQL SELECT命令作为参数,该参数必须符合以下限制:

  • SELECT必须返回3列。
  • SELECT中的第一列将是数据透视表或最终结果中每一行的标识符。在我们的例子中,这是学生的名字。注意学生的名字(John Smith和Peter Gabriel)是如何出现在第一列中的。
  • SELECT中的第二列表示透视表中的类别。在我们的例子中,这些类别是学校的科目。需要注意的是,该列的值将扩展到数据透视表中的许多列中。如果第二列返回5个不同的值(地理、历史等),则数据透视表将有5列。
  • SELECT中的第三列表示分配给数据透视表的每个单元格的值。这些是我们示例中的求值结果。

如果我们把数据透视表看作一个二维数组,那么第一个SELECT列是数组的第一个维度,第二个SELECT列是第二个维度,第三个是数组元素的值。比如grid [first_column_value, second_column_value] = third_column_value。

SELECT student, subject, evaluation_result FROM evaluations ORDER BY 1,2

crosstab 函数在SELECT语句的FROM子句中调用。我们必须定义将进入最终结果的列和数据类型的名称。就我们的目的而言,最终结果定义为:

AS final_result(Student TEXT, Geography NUMERIC,History NUMERIC,Language NUMERIC,Maths NUMERIC,Music NUMERIC)

整合上面的内容,完整的语句:

SELECT *
FROM crosstab( 'select student, subject, evaluation_result from evaluations order by 1,2')
     AS final_result(Student TEXT, Geography NUMERIC,History NUMERIC,Language NUMERIC,Maths NUMERIC,Music NUMERIC);

查询结果如下:

StudentGeographyHistoryLanguageMathsMusic
Gabriel, Peter10.07.04.010.02.0
Smith, John9.09.07.04.07.0

透视表实战示例

从单个数据集,我们可以生成许多不同的数据透视表。让我们继续以教师和班级为例,看看我们的一些选项。

查询学生每月成绩

作为老师,我们可能还需要一份学生今年迄今为止的评估结果报告。例如,假设我们想要获得约翰·史密斯从3月到7月的平均评价。在如下的网格中,表格看起来是这样的:

month textgeography numerichistory numericlanguage numericmaths numericmusic numeric
39.009.007.004.007.00
44.007.507.004.005.66
58.006.007.007.007.00
67.507.007.007.008.00
76.669.007.7510.006.00

实现透视表SQL:

SELECT *
FROM crosstab( 'select extract(month from period)::text, subject.name,
             trunc(avg(evaluation_result),2)
     from evaluation, subject 
     where evaluation.subject_id = subject.subject_id and student_id = 1
     group by 1,2 order by 1,2')  AS final_result(Month TEXT, Geography NUMERIC,History NUMERIC,Language NUMERIC,Maths NUMERIC,Music NUMERIC);

处理不完整记录

我们也可以称这一节为“交叉表的限制以及如何解决它”。在讨论这个问题之前,让我们先来设定一下场景:

假设你想看看是否有些学生在某些科目上没有考试分数。也许你可以尝试前面的查询,为July添加一个WHERE子句。代码看起来像这样:

SELECT *
FROM crosstab( 'select student, subject, evaluation_result from evaluations where extract (month from evaluation_day) = 7 order by 1,2')
     AS final_result(Student TEXT, Geography NUMERIC,History NUMERIC,Language NUMERIC,Maths NUMERIC,Music NUMERIC);

下面的数据透视表是该查询的结果。我们很快就可以看到,我们没有给彼得的语言、数学和音乐评分。

StudentGeographyHistoryLanguageMathsMusic
Gabriel, Peter10.06.07.00
Smith, John6.08.06.09.04.0

但是,如果我们尝试常规查询以获得Peter在7月份的成绩……

SELECT * from evaluations
where extract ( month from evaluation_day)=7 and student like 'Gabriel, Peter'

我们获得了不同的结果:

studentsubjectevaluation_resultevaluation_day
Gabriel, PeterLanguage6.02016-07-15
Gabriel, PeterGeography10.02016-07-04

当然,第二个查询是正确的,因为它显示的是原始数据。问题是数据透视表构建过程中,有些种类的信息缺失。为了解决这个问题,我们可以使用带有第二个参数的交叉表函数,该参数表示完整的类别列表。如果存在缺失值,数据透视表仍将正确构建。

第二个参数内容:‘select name from subject order by 1’ ,完整语句如下:

SELECT *
FROM crosstab( 'select student, subject, evaluation_result from evaluations
                where extract (month from evaluation_day) = 7 order by 1,2',
                'select name from subject order by 1')
     AS final_result(Student TEXT, Geography NUMERIC,History NUMERIC,Language NUMERIC,Maths NUMERIC,Music NUMERIC);

现在输出结果包括缺失科目,并使用–表示:

StudentGeographyHistoryLanguageMathsMusic
Gabriel, Peter10.06.0
Smith, John6.08.06.09.04.0

练习数据

数据透视表为我们提供了一种不同的方式来查看数据。此外,我们可以使用交叉表函数基于相同的原始数据创建不同的数据透视表。尝试构建一个数据透视表,根据下表中的原始数据显示每个城市和月份的最高温度。

CREATE TABLE weather (city text, when timestamp, temperature float);
CityWhenTemperature
Miami2016-01-01 08:00:0068.6
Miami2016-01-21 08:00:0073.3
Orlando2016-01-01 08:00:0072.5
Miami2016-02-01 18:00:0058.6
Orlando2016-02-02 18:00:0062.5
Miami2016-03-03 08:00:0055.6
Orlando2016-03-03 08:00:0056.7
Miami2016-04-04 18:00:0050.6
Orlando2016-04-04 18:00:0061.5

数据透视表应为每个城市有一行,每个月有一列。如果你愿意,可以考虑使用相同的数据制作其他数据透视表。卷起袖子,试试吧。

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

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

相关文章

生信软件开发1 - 设计一个简单的Windwos风格的GUI报告软件

1. 安装基础库 使用Windows 11标题样式和主题自定义UI窗口库pywinstyles(github: https://github.com/Akascape/py-window-styles),结合python自带tkinter库设计一个报告GUI软件。 pip install pywinstyles2. 设计一个简单的Windwos风格的G…

navicat连接mysql 8.0以上版本2059错误

安装了最新版本8.0.4的mysql之后,使用navicat链接提示以下错误。原因是因为mysql8.0 之前的版本中加密规则是 mysql_native_password,而 mysql8.0 之后的版本加密规则是caching_sha2_password 处理方案 解决方案1:下载安装最新版本navicat…

使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像

文章目录 应用快速部署NginxRedisMySQLTomcat 制作镜像镜像原理基于已有容器创建使用 Dockerfile 创建镜像指令说明构建应用创建 Dockerfile 文件创建镜像 应用快速部署 Nginx docker run -d -p 80:80 nginx使用浏览器访问虚拟机地址 Redis docker pull redis docker run --…

【PlantUML系列】类图(一)

目录 一、类 二、接口 三、抽象类 四、泛型类 五、类之间的关系 六、添加注释 七、包图 八、皮肤参数 一、类 使用class关键字定义类,类名后跟大括号,声明类的属性和方法。 属性:格式为{visibility} attributeName : AttributeType…

VR眼镜可视化编程:开启医疗信息系统新纪元

一、引言 随着科技的飞速发展,VR 可视化编程在医疗信息系统中的应用正逐渐成为医疗领域的新趋势。它不仅为医疗教育、手术培训、疼痛管理等方面带来了新的机遇,还在提升患者体验、推动医疗信息系统智能化等方面发挥着重要作用。 在当今医疗领域&#xf…

IS-IS的原理

IS-IS的基本概念: 概述: IS-IS,中间系统到中间系统,是ISO国际标准化组织为它的无连接网络协议设计的一种动态路由协议 IS-IS支持CLNP网络和IP网络,采用数据链路层封装,区别于ospf只支持IP网络&#xff0…

华为ACL应用笔记

1、基本ACL 2000-2999 基本ACL(Access Control List,访问控制列表)是一种网络安全技术,它根据源IP地址、分片信息和生效时间段等信息来定义规则,对报文进行过滤。 规则: ACL由一系列规则组成,每…

点云标注软件SUSTechPOINTS的安装和使用,自测win10和ubuntu20.04下都可以用

点云标注软件SUSTechPOINTS的安装和使用 github项目源码:https://github.com/naurril/SUSTechPOINTS gitee源码以及使用教程:https://gitee.com/cuge1995/SUSTechPOINTS 首先拉取源码 git clone https://github.com/naurril/SUSTechPOINTS最好是在cond…

大模型评测中的基础指标都包括哪些

大语言模型(LLM)评测是LLM开发和应用中的关键环节。目前评测方法可以分为人工评测和自动评测,其中,自动评测技术相比人工评测来讲,具有效率高、一致性好、可复现、鲁棒性好等特点,逐渐成为业界研究的重点。…

SystemUI修改状态栏电池图标样式为横屏显示(以Android V为例)

SystemUI修改状态栏电池图标样式为横屏显示(以Android V为例) 1、概述 在15.0的系统rom产品定制化开发中,对于原生系统中SystemUId 状态栏的电池图标是竖着显示的,一般手机的电池图标都是横屏显示的 可以觉得样式挺不错的,所以由于产品开发…

最长最短单词

最长最短单词 C语言实现C实现Java实现Python实现 💐The Begin💐点点关注,收藏不迷路💐 输入1行句子(不多于200个单词,每个单词长度不超过100),只包含字母、空格和逗号。单词由至少一…

C++【PCL】点云数据平移 旋转,对点云进行刚体变化

//头文件 #include <iostream>#include <pcl/point_cloud.h>#include<pcl/io/pcd_io.h>#include <pcl/common/transforms.h> #include <pcl/io/ply_io.h>//主函数int main() {pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud(new pcl::…

2024第六届金盾信安杯Web 详细题解

比赛一共4道Web题,比赛时只做出三道,那道文件上传没有做出来,所以这里是另外三道题的WP 分别是 fillllll_put hoverfly ssrf fillllll_put 涉及: 绕过exit() 死亡函数 php://filter 伪协议配合base64加解密 一句话木马 题目源码&#xff1a; $content参数在开头被…

006 MATLAB编程基础

01 M文件 MATLAB输入命令有两种方法&#xff1a; 一是在MATLAB主窗口逐行输入命令&#xff0c;每个命令之间用分号或逗号分隔&#xff0c;每行可包含多个命令。 二是将命令组织成一个命令语句文集&#xff0c;使用扩展名“.m”&#xff0c;称为M文件。它由一系列的命令和语句…

Delphi Web前端开发教程(9):基于TMS WEB Core框架

3、REST Servers服务端(后端)框架 REST服务端特点&#xff1a; – 为远程资源提供一个REST API接口。也可以为其他网络内容提供服务&#xff1b; – 包括在Delphi Enterprise & Architect企业版和架构师版中的RAD服务器、DataSnap、WebBroker&#xff1b; – 开源框架&a…

SPC三种判定准则的算法

1.连续6个点递增或递减 //传入数据列表 //返回连续X个及以上递增或递减的数组下标int n = array.Length; int X = X_in; List<int> regions_start = new List<int>(); List<int> regions_end = new List<int>();if(Open){for (int i = 0; i < n - (…

AI一键生成原创圣诞印花图案

一、引言 随着科技的飞速发展&#xff0c;AI 已经深入到我们生活和工作的各个角落&#xff0c;为创意设计领域带来了前所未有的变革。在圣诞即将来临之际&#xff0c;想要设计独特的圣诞印花图案却又担心缺乏灵感或专业技能&#xff1f;别担心&#xff0c;千鹿 AI 为我们提供了…

Ubuntu的pip怎么用

第一步&#xff1a;查看python3版本 第二步&#xff1a;安装pip 第三步&#xff1a;可以尝试使用pip list查看 也可以尝试安装 下面这条命令可以设置永久源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

基于Matlab三点雨流计数法的载荷时间历程分析与循环疲劳评估

随着工程领域中机械设备和结构系统的复杂性不断增加&#xff0c;疲劳分析成为评估其可靠性与使用寿命的关键环节。载荷时间历程数据在疲劳分析中扮演着重要角色&#xff0c;而雨流计数法作为经典的循环计数方法&#xff0c;能够有效地从载荷时间历程中提取疲劳载荷循环信息。本…

帝可得-策略管理

策略管理 需求说明 策略管理主要涉及到二个功能模块&#xff0c;业务流程如下&#xff1a; 新增策略: 允许管理员定义新的策略&#xff0c;包括策略的具体内容和参数&#xff08;如折扣率&#xff09;策略分配: 将策略分配给一个或多个售货机。 #mermaid-svg-PSQOJMLJqVGn3W…