PostgreSQL实现透视表查询

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 = 1group 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 evaluationswhere 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.mzph.cn/diannao/62923.shtml

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

相关文章

使用Tauri创建桌面应用

当前是在 Windows 环境下 1.准备 系统依赖项 Microsoft C 构建工具WebView2 (Windows10 v1803 以上版本不用下载,已经默认安装了) 下载安装 Rust下载安装 Rust 需要重启终端或者系统 重新打开cmd,键入rustc --version,出现 rust 版本号&…

【掩体计划——DFS+缩点】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e5 10; vector<vector<int>> g; bool st[N]; int ans 1e9; bool dfs(int f, int u, int dis) {bool is 1;for (auto j : g[u]){if (j f)continue;is & dfs(u, j, dis (g[u].…

游戏引擎学习第25天

Git: https://gitee.com/mrxiao_com/2d_game 今天的计划 总结和复述&#xff1a; 这段时间的工作已经接近尾声&#xff0c;虽然每次编程的时间只有一个小时&#xff0c;但每一天的进展都带来不少收获。尽管看起来似乎花费了很多时间&#xff0c;实际上这些日积月累的时间并未…

《Python基础》之Pandas库

目录 一、简介 二、Pandas的核心数据结构 1、Series 2、DataFrame 三、数据读取与写入 1、数据读取 2、数据写入 四、数据清洗与处理 1、处理缺失值 2、处理重复值 3、数据转换 五、数据分析与可视化 1、统计描述 2、分组聚合 3、数据可视化 六、高级技巧 1、时…

设计模式 更新ing

设计模式 1、六大原则1.1 单一设计原则 SRP1.2 开闭原则1.3 里氏替换原则1.4 迪米特法则1.5 接口隔离原则1.6 依赖倒置原则 2、工厂模式 1、六大原则 1.1 单一设计原则 SRP 一个类应该只有一个变化的原因 比如一个视频软件&#xff0c;区分不同的用户级别 包括访客&#xff0…

c++预编译头文件

文章目录 c预编译头文件1.使用g编译预编译头文件2.使用visual studio进行预编译头文件2.1visual studio如何设置输出预处理文件&#xff08;.i文件&#xff09;2.2visual studio 如何设置预编译&#xff08;初始创建空项目的情况下&#xff09;2.3 visual studio打开输出编译时…

SeggisV1.0 遥感影像分割软件【源代码】讲解

在此基础上进行二次开发&#xff0c;开发自己的软件&#xff0c;例如&#xff1a;【1】无人机及个人私有影像识别【2】离线使用【3】变化监测模型集成【4】个人私有分割模型集成等等&#xff0c;不管是您用来个人学习还是公司研发需求&#xff0c;都相当合适&#xff0c;包您满…

echarts地图立体效果,echarts地图点击事件,echarts地图自定义自定义tooltip

一.地图立体效果 方法1:两层地图叠加 实现原理:geo数组中放入两个地图对象,通过修改zlevel属性以及top,left,right,bottom形成视觉差 配置项参考如下代码: geo: [{zlevel: 2,top: 96,map: map,itemStyle: {color: #091A51ee,opacity: 1,borderWidth: 2,borderColor: #16BAFA…

HTML 快速上手

目录 一. HTML概念 二. HTML标签 1. 标题标签 2. 段落标签 3. 换行标签 4. 图片标签 5. 超链接标签 6. 表格标签 7. 表单标签 7.1 form 标签 7.2 input 标签 (1) 文本框 (2) 单选框 (3) 密码框 (4) 复选框 (5) 普通按钮 (6) 提交按钮 8. select标签 9. 无语义…

Linux 各个目录作用

刚毕业的时候学习Linux基础知识&#xff0c;发现了一份特别好的文档快乐的 Linux 命令行&#xff0c;翻译者是happypeter&#xff0c;作者当年也在慕课录制了react等前端相关的视频&#xff0c;通俗易懂&#xff0c;十分推荐 关于Linux的目录&#xff0c;多数博客已有详细介绍…

Fastapi + vue3 自动化测试平台---移动端App自动化篇

概述 好久写文章了&#xff0c;专注于新框架&#xff0c;新UI界面的实践&#xff0c;废话不多说&#xff0c;开搞 技术架构 后端&#xff1a; Fastapi Airtest multiprocessing 前端&#xff1a; 基于 Vue3、Vite、TypeScript、Pinia、Pinia持久化插件、Unocss 和 Elemen…

详解Vue设计模式

详解 vue 设计模式 ​ Vue.js 作为一个流行的前端框架&#xff0c;拥有许多设计模式&#xff0c;这些设计模式帮助开发者更好地组织和管理代码&#xff0c;提升代码的可维护性、可扩展性和可读性。Vue 设计模式主要体现在以下几个方面&#xff1a; 1. 组件化设计模式 (Compon…

了解Linux —— 理解其中的权限

前言 在了解Linux权限之前&#xff0c;先来探讨我们使用的shell 命令它到底是什么&#xff1f; Linux 是一个操作系统&#xff0c;我们称其为内核(kernel) &#xff0c;正常情况下&#xff0c;我们一般用户操作并不是去直接使用内核&#xff0c;而是通过kernel 的外壳程序&…

WebHID API演示Demo教程:设备列表,设备连接,数据读写

1. 简介 WebHID API允许网页应用直接与HID&#xff08;人机接口设备&#xff09;进行通信。本教程将演示如何创建一个基础的WebHID应用&#xff0c;实现以下功能&#xff1a; 显示和获取HID设备列表连接/断开HID设备读取设备数据向设备发送数据 2. 兼容性和前提条件 2.1 浏览…

中安证件OCR识别技术助力鸿蒙生态:智能化证件识别新体验

在数字化和智能化的浪潮中&#xff0c;伴随国产化战略的深入推进&#xff0c;国产操作系统和软件生态的建设逐渐走向成熟。鸿蒙操作系统&#xff08;HarmonyOS Next&#xff09;作为华为推出的重要操作系统&#xff0c;凭借其开放、灵活和高效的特点&#xff0c;正在加速在多个…

PDF与PDF/A的区别及如何使用Python实现它们之间的相互转换

目录 概述 PDF/A 是什么&#xff1f;与 PDF 有何不同&#xff1f; 用于实现 PDF 与 PDF/A 相互转换的 Python 库 Python 实现 PDF 转 PDF/A 将 PDF 转换为 PDF/A-1a 将 PDF 转换为 PDF/A-1b 将 PDF 转换为 PDF/A-2a 将 PDF 转换为 PDF/A-2b 将 PDF 转换为 PDF/A-3a 将…

面向对象(二)——类和对象(上)

1 类的定义 做了关于对象的很多介绍&#xff0c;终于进入代码编写阶段。 本节中重点介绍类和对象的基本定义&#xff0c;属性和方法的基本使用方式。 【示例】类的定义方式 // 每一个源文件必须有且只有一个public class&#xff0c;并且类名和文件名保持一致&#xff01; …

【HarmonyOS】鸿蒙应用地理位置获取,地理名称获取

【HarmonyOS】鸿蒙应用地理位置获取&#xff0c;地理名称获取 一、前言 首先要理解地理专有名词&#xff0c;当我们从系统获取地理位置&#xff0c;一般会拿到地理坐标&#xff0c;是一串数字&#xff0c;并不是地理位置名称。例如 116.2305&#xff0c;33.568。 这些数字坐…

关于数据库数据国际化方案

方案一&#xff1a;每个表设计一个翻译表 数据库国际化的应用场景用到的比较少&#xff0c;主要用于对数据库的具体数据进行翻译&#xff0c;在需要有大量数据翻译的场景下使用&#xff0c;举个例子来说&#xff0c;力扣题目的中英文切换。参考方案可见&#xff1a; https://b…

「Mac畅玩鸿蒙与硬件37」UI互动应用篇14 - 随机颜色变化器

本篇将带你实现一个随机颜色变化器应用。用户点击“随机颜色”按钮后&#xff0c;界面背景会随机变化为淡色系颜色&#xff0c;同时显示当前的颜色代码&#xff0c;页面还会展示一只猫咪图片作为装饰&#xff0c;提升趣味性。 关键词 UI互动应用随机颜色生成状态管理用户交互…