重塑表格以将行转换为列

2023-12-04

我尝试搜索帖子,但只找到了 SQL Server/Access 的解决方案。我需要 MySQL (5.X) 中的解决方案。

我有一个包含 3 列的表(称为历史记录):hostid、itemname、itemvalue。
如果我做一个选择(select * from history),它将返回

   +--------+----------+-----------+
   | hostid | itemname | itemvalue |
   +--------+----------+-----------+
   |   1    |    A     |    10     |
   +--------+----------+-----------+
   |   1    |    B     |     3     |
   +--------+----------+-----------+
   |   2    |    A     |     9     |
   +--------+----------+-----------+
   |   2    |    C     |    40     |
   +--------+----------+-----------+

如何查询数据库以返回类似的内容

   +--------+------+-----+-----+
   | hostid |   A  |  B  |  C  |
   +--------+------+-----+-----+
   |   1    |  10  |  3  |  0  |
   +--------+------+-----+-----+
   |   2    |   9  |  0  |  40 |
   +--------+------+-----+-----+

我将添加一个更长、更详细的说明来说明解决此问题所需的步骤。如果太长,我深表歉意。


我将从您给出的基础开始,并用它来定义几个术语,我将在本文的其余部分使用这些术语。这将是基表:

select * from history;

+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
|      1 | A        |        10 |
|      1 | B        |         3 |
|      2 | A        |         9 |
|      2 | C        |        40 |
+--------+----------+-----------+

这将是我们的目标,漂亮的数据透视表:

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

值在history.hostid列将成为y-values在数据透视表中。值在history.itemname列将成为x-values(出于显而易见的原因)。


当我必须解决创建数据透视表的问题时,我使用三步过程来解决它(还有可选的第四步):

  1. 选择感兴趣的列,即y-values and x-values
  2. 用额外的列扩展基表——每列一个x-value
  3. 对扩展表进行分组和聚合——每个表一组y-value
  4. (可选)美化聚合表

让我们将这些步骤应用于您的问题,看看会得到什么:

第 1 步:选择感兴趣的列。在想要的结果中,hostid提供了y-values and itemname提供了x-values.

步骤 2:使用额外列扩展基表。我们通常需要每个 x 值一列。回想一下我们的 x 值列是itemname:

create view history_extended as (
  select
    history.*,
    case when itemname = "A" then itemvalue end as A,
    case when itemname = "B" then itemvalue end as B,
    case when itemname = "C" then itemvalue end as C
  from history
);

select * from history_extended;

+--------+----------+-----------+------+------+------+
| hostid | itemname | itemvalue | A    | B    | C    |
+--------+----------+-----------+------+------+------+
|      1 | A        |        10 |   10 | NULL | NULL |
|      1 | B        |         3 | NULL |    3 | NULL |
|      2 | A        |         9 |    9 | NULL | NULL |
|      2 | C        |        40 | NULL | NULL |   40 |
+--------+----------+-----------+------+------+------+

请注意,我们没有更改行数——我们只是添加了额外的列。还要注意图案NULLs——一行itemname = "A"新列具有非空值A,以及其他新列的空值。

步骤3:对扩展表进行分组聚合。我们需要group by hostid,因为它提供了 y 值:

create view history_itemvalue_pivot as (
  select
    hostid,
    sum(A) as A,
    sum(B) as B,
    sum(C) as C
  from history_extended
  group by hostid
);

select * from history_itemvalue_pivot;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 | NULL |
|      2 |    9 | NULL |   40 |
+--------+------+------+------+

(请注意,现在每个 y 值一行。)好的,我们快到了!我们只需要摆脱那些丑陋的NULLs.

第四步:美化。我们将用零替换任何空值,以便结果集看起来更好:

create view history_itemvalue_pivot_pretty as (
  select 
    hostid, 
    coalesce(A, 0) as A, 
    coalesce(B, 0) as B, 
    coalesce(C, 0) as C 
  from history_itemvalue_pivot 
);

select * from history_itemvalue_pivot_pretty;

+--------+------+------+------+
| hostid | A    | B    | C    |
+--------+------+------+------+
|      1 |   10 |    3 |    0 |
|      2 |    9 |    0 |   40 |
+--------+------+------+------+

我们就完成了——我们已经使用 MySQL 构建了一个漂亮的数据透视表。


应用此程序时的注意事项:

  • 在额外的列中使用什么值。我用了itemvalue在这个例子中
  • 在额外的列中使用什么“中性”值。我用了NULL,但也可能是0 or "",根据您的具体情况
  • 分组时使用什么聚合函数。我用了sum, but count and max也经常使用(max在构建分布在多行中的单行“对象”时经常使用)
  • 使用多列作为 y 值。此解决方案不限于使用单个列作为 y 值 - 只需将额外的列插入group by条款(并且不要忘记select them)

已知限制:

  • 此解决方案不允许数据透视表中有 n 列——扩展基表时需要手动添加每个数据透视列。因此,对于 5 或​​ 10 个 x 值,此解决方案很好。 100块,不太好。有一些使用存储过程生成查询的解决方案,但它们很丑陋并且很难正确执行。当数据透视表需要有很多列时,我目前不知道解决这个问题的好方法。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重塑表格以将行转换为列 的相关文章

  • 选择每组最新的项目[重复]

    这个问题在这里已经有答案了 可能的重复 检索每组中的最后一条记录 https stackoverflow com questions 1313120 retrieving the last record in each group 我有 2
  • 从 SQL Server 中的子查询值或其他聚合函数获取平均值

    我有 SQL 语句 SQL Server SELECT COUNT ActionName AS pageCount FROM tbl 22 Benchmark WHERE DATEPART dw CreationDate gt 1 AND
  • pyodbc 无法正确处理 unicode 数据

    我确实使用 pyodbc 成功连接了 MySQL 数据库 并且它可以很好地处理 ascii 编码的数据 但是当我打印使用 unicode utf8 编码的数据时 它引发了错误 UnicodeEncodeError ascii codec c
  • DBX 错误:驱动程序无法正确初始化

    我在跑步德尔福XE3 终极版 MySQL 数据库 这是我点击时收到的错误Test Connection 作为回应 我在 xampp 目录中找到了 libmysql 库 并将其复制到我的 System32 目录中 但这是行不通的 此消息指的是
  • 日常 MySQL(部分和过滤)复制的最佳实践?

    我有一个相当大的数据库 有超过 40 个表 我只需要复制几个表 5 并且每个表也被过滤 我正在寻找一些复制这些数据的最佳实践 每天就足够了 我可以只选择几个表并为每个表包含一些 WHERE 子句 我正在考虑为每个表启动 mysqldump
  • TSQL:无法对 COUNT(*) 执行聚合函数 AVG 来查找一天中最繁忙的时间

    考虑一个保存日志数据的 SQL Server 表 重要的部分是 CREATE TABLE dbo CustomerLog ID int IDENTITY 1 1 NOT NULL CustID int NOT NULL VisitDate
  • 通过 PDO 将双精度数插入 MySQL 时精度损失

    我遇到了这种非常烦人的行为 我想知道我是否做错了什么 或者这是否是故意的 如果是的话 为什么 每当我在 php 5 3 中有一个 double 类型的变量 并且想将其插入到数据库 MYSQL 5 0 的 double 类型字段中时 该值总是
  • 无法从 Web 主机本身以外的任何地方连接到任何 Web 主机的 MySQL 数据库

    我有 2 个不同的虚拟主机 pagodabox 000webhost 都是免费的 并且我已经设置了localhost与MySQL 我已经在他们三个上安装了 wordpress 它们在自己的域中工作得很好 即 什么时候localhostwor
  • Mysql关于重复键更新+子查询

    使用这个问题的答案 需要 MySQL INSERT SELECT 查询具有数百万条记录的表 https stackoverflow com questions 662877 need mysql insert select query fo
  • 软删除最佳实践(PHP/MySQL)

    Problem 在处理产品和订单的 Web 应用程序中 我想维护前员工 用户 与他们处理的订单之间的信息和关系 我想维护过时产品和包含这些产品的订单之间的信息和关系 然而 我希望员工能够整理管理界面 例如删除前员工 过时的产品 过时的产品组
  • 将我的 Laravel 连接到外部数据库

    如何将 Laravel 连接到外部数据库 示例 我的本地计算机上有一个 Laravel 它在 xampp 上运行 我希望它连接到云服务器数据库 打开 env文件并编辑它 只需设置正确的外部数据库凭据 DB CONNECTION mysql
  • MySQL 将表的校验和存储在另一个表中

    语境 我们有包含大量表的大型数据库 他们中的大多数 99 都使用innodb 我们希望有一个日常流程来监视哪个表已被修改 当他们使用 innodb 的值时Update time from SHOW table STATUS from inf
  • SQL 查询结果为字符串(或变量)

    是否可以将SQL查询结果输出到一个字符串或变量中 我的php和mysql不好 假设我有数据库 agents 其中包含列 agent id agent fname agent lname agent dept 使用此查询 sql SELECT
  • 如何显示 RSpec 测试生成的 SQL 查询日志?

    我正在为我的 Rails 3 应用程序编写规范 我想测试数据库事务是否真的有效 如果能够看到我的应用程序在规范驱动下生成的 sql 查询 这将非常有帮助 有没有办法像在 Rails 控制台中一样查看查询 我正在使用 Rails 3 0 9
  • 使用显式值进行 BigQuery 合并

    据我所知 BigQuery 支持合并两个表 目前 INSERT操作允许将显式值插入表中 例如 INSERT dataset Inventory product quantity VALUES top load washer 10 front
  • 关于 Cassandra 与 MySQL 的一些建议

    几天前我在这里问了一个问题 得到了一些非常好的答案 我正在考虑做一个带有个人资料 个人简介等的facebook风格的网站 并询问我是否应该使用mysql 答案是使用Cassandra 因为好多了 我只是问这是每个人都会建议的 只是我对mys
  • Solr 增量导入不起作用

    我使用的是solr 4 2 请注意 完全导入有效 但增量导入却无效 增量导入不会给出任何错误 但不会获取任何更改 这是数据配置文件
  • 常量值如何影响连接的 ON 子句?

    我最近发现 LEFT JOIN 的 ON 子句可能包含 1 1 等值 这让我感到不安 因为它打破了我对连接功能的看法 我遇到过以下情况的更详细版本 SELECT DISTINCT Person ID FROM Person LEFT JOI
  • SQL Server 标识列值从 0 而不是 1 开始

    我遇到了一个奇怪的情况 数据库中的某些表的 ID 从 0 开始 即使 TABLE CREATE 的 IDENTITY 1 1 也是如此 对于某些表来说是这样 但对于其他表则不然 它一直有效到今天 我尝试过重置身份列 DBCC CHECKID
  • Postgresql:SERIAL 在约束 INSERT 失败时递增

    有一个像这样的简单表结构 CREATE TABLE test id INT PRIMARY KEY sid SERIAL 我注意到如果我尝试插入一行但它未通过约束测试 即主键约束 SERIAL计数器无论如何都会增加 所以下一次成功插入 si

随机推荐

  • 将 RDD 转换为 JSON 对象

    我有一个 RDD String List String 类型的 RDD 例子 FRUIT List Apple Banana Mango VEGETABLE List Potato Tomato 我想将上面的输出转换为 json 对象 如下
  • 如何让JTextArea粘在窗口上

    您好 我想让这个 TextArea 在通过鼠标调整大小时坚持窗口大小 就像下部按钮一样 这是代码 它运行完美 没有错误 请看一下 import java awt BorderLayout import java awt Component
  • 有没有办法在 Rust 中删除静态生命周期对象?

    在寻找答案时我发现这个问题 但是没有提到静态生命周期对象 这个答案中提到的方法可以吗 调用drop 在对象上 可用于静态生命周期对象吗 我想象了一种类似链表的情况 您需要 可能 在程序的整个生命周期中保留列表的节点 但是您也可以从列表中删除
  • 如果我的 Android Web 视图中没有可用的互联网,如何显示消息

    您好 我正在使用 android webview 应用程序 我在我的应用程序中成功使用了我的 url 并且仅当互联网连接可用时它才有效 但是我想在没有互联网连接时显示一些消息 我该怎么做 请帮助我 因为我是 Android 开发新手 谢谢
  • JavaLaunchHelper 类在两者中均实现。将使用两者之一。哪一个未定义[重复]

    这个问题在这里已经有答案了 在 Mac OS X 上的 Eclipse Kepler 上使用 java 版本 1 7 0 45 有一个简单的 Google App Engine Web 应用程序项目 遇到以下情况 objc 5398 Cla
  • D3 Dimple - 如何在同一页面上显示多个凹坑图表?

    I m making an html page with several examples of charts that I will be using On the page I have a Dimple line graph a pi
  • 使用 forRoot 传递在库中导入的 angularFire 配置

    我在自定义库中使用 angularFire2 NgModule imports CommonModule AngularFireModule initializeApp firebaseConfig AngularFirestoreModu
  • 如何在基于类的组件中使用 React.forwardRef?

    我正在尝试使用 React forwardRef 但不知道如何让它在基于类的组件 而不是 HOC 中工作 文档示例使用元素和函数组件 甚至将类包装在高阶组件的函数中 所以 从类似的事情开始this在他们的ref js file const
  • 如何使 UITableView 与大标题 VoiceOver 兼容?

    我的应用程序有一个表格视图 其中有一个大的空白 tableHeaderView 允许将可见单元格完全滚动到窗口之外 到底部 所以 contentOffset 为 0 0 意味着内容被滚动到窗口之外 初始 contentOffset 为 0
  • 显式转换函数、直接初始化和转换构造函数

    后标准草案 n3376 有一个使用显式转换函数到用户定义类型的示例 12 3 2 2 class Y struct Z explicit operator Y const void h Z z Y y1 z OK direct initia
  • 编写存储过程来获取 Jqgrid 分页数据的困难

    我正在使用以下 SQL 过程来获取用于我的 Web 应用程序中 JqGrid 分页的数据 ALTER PROCEDURE dbo NewStoredProc skip int pageSize int OrderBy Varchar 20
  • 检测快速按两次电源按钮

    是否可以检测用户是否快速按下电源按钮两次 Apple 使用这种方式在带有 Face ID 的新款 iPhone X 上确认 Appstore 购买 有可用的API吗 希望在类似情况下使用它通过 Face ID 进行身份验证 不会 系统本身控
  • 将 YAML 与变量一起使用

    YAML 文件中可以使用变量吗 例如 theme name default css path compiled themes theme name layout path themes theme name 在这个例子中 如何theme n
  • Mac OS X 上 sqlite4java Jar 出现 UnsatisfiedLinkError

    我在 Java 应用程序中使用 sqlite4java 库 当我在 Eclipse 中运行它时它工作得很好 但是当我构建可运行的 JAR 并尝试在 Mac OS X 上运行它时 出现以下错误 Error Could not load dat
  • C# DLL 配置文件

    我试图将 app config 文件添加到我的 DLL 中 但所有尝试都失败了 据 音乐创世纪 报道 将配置信息放入 DLL 中 这应该不是问题 所以显然我做错了什么 以下代码应从 DLL 返回我的 ConnectionString ret
  • 使用 VBA 方法通过 Bing API 获取距离

    我试图通过 VBA 创建一个方法 当我使用此方法时 它显示 NAME 有时 value Public Function DISTANCE start As String dest As String key As String Dim fi
  • Objective-C UITableView 单元格图像

    所以我有一个UI表格视图Facebook 好友和一个单元格 我想将图像添加到其中 当我尝试以下代码时 cell imageView image UIImage imageWithData NSData dataWithContentsOfU
  • 从数据库或属性获取 Spring Security 拦截 url

    希望这非常简单 存在 并且我忽略了我眼皮底下的一些东西 我知道我可以通过注释限制访问 Secured ROLE ADMIN 或通过配置
  • UIButton标题消失

    我有一个 ViewController 里面有一个 UIButton 当我点击时 按钮上的文字消失了 我为所有状态添加了所有 setTitle 但它继续消失 任何想法 这是我的代码的一部分 interface AddCardViewCont
  • 重塑表格以将行转换为列

    我尝试搜索帖子 但只找到了 SQL Server Access 的解决方案 我需要 MySQL 5 X 中的解决方案 我有一个包含 3 列的表 称为历史记录 hostid itemname itemvalue 如果我做一个选择 select