相当于 PostgreSQL 中的 unpivot()
PostgreSQL 中是否有 unpivot 等效函数?
Is there a unpivot equivalent function in PostgreSQL?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
PostgreSQL 中是否有 unpivot 等效函数?
Is there a unpivot equivalent function in PostgreSQL?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
创建一个示例表:
您可以使用 UNION ALL 进行“unpivot”或“uncrosstab”:
这会在
foo
上运行 3 个不同的子查询,每个子查询对应我们要取消透视的每一列,并在一个表中返回每个每个子查询的记录。但这将扫描表 N 次,其中 N 是要逆透视的列数。 这是低效的,并且是一个大问题,例如,当您正在使用需要很长时间扫描的非常大的表时。
相反,使用:
这更容易编写,并且只会扫描表一次。
array[a, b, c]
返回一个数组对象,其中 a、b 和 c 的值作为其元素。unnest(array[a, b, c])
< /a> 将数组每个元素的结果分成一行。Create an example table:
You can 'unpivot' or 'uncrosstab' using UNION ALL:
This runs 3 different subqueries on
foo
, one for each column we want to unpivot, and returns, in one table, every record from each of the subqueries.But that will scan the table N times, where N is the number of columns you want to unpivot. This is inefficient, and a big problem when, for example, you're working with a very large table that takes a long time to scan.
Instead, use:
This is easier to write, and it will only scan the table once.
array[a, b, c]
returns an array object, with the values of a, b, and c as it's elements.unnest(array[a, b, c])
breaks the results into one row for each of the array's elements.您可以使用
VALUES()
并加入横向
取消旋转列。示例数据:
查询:
DBFiddle Demo
使用这种方法可以同时取消透视多组列。
编辑
使用Zack的建议:
db<>fiddle 演示
You could use
VALUES()
andJOIN LATERAL
to unpivot the columns.Sample data:
Query:
DBFiddle Demo
Using this approach it is possible to unpivot multiple groups of columns at once.
EDIT
Using Zack's suggestion:
db<>fiddle demo
托马斯·凯勒 (Thomas Kellerer) 的精彩文章此处
使用 Postgres 进行逆透视
有时需要对非规范化表进行规范化 - 与“交叉表”或“透视”操作相反。 Postgres 不支持像 Oracle 或 SQL Server 这样的 UNPIVOT 运算符,但是模拟它非常简单。
采用下表存储每个季度的聚合值:
以及以下示例数据:
但我们希望季度是行(因为它们应该在标准化数据模型中)。
在 Oracle 或 SQL Server 中,这可以通过 UNPIVOT 运算符来实现,但这在 Postgres 中不可用。 然而,Postgres 像表一样使用 VALUES 子句的能力使得这实际上非常容易:
将返回以下结果:
使用标准 UNPIVOT 运算符的等效查询将是:
Great article by Thomas Kellerer found here
Unpivot with Postgres
Sometimes it’s necessary to normalize de-normalized tables - the opposite of a “crosstab” or “pivot” operation. Postgres does not support an UNPIVOT operator like Oracle or SQL Server, but simulating it, is very simple.
Take the following table that stores aggregated values per quarter:
And the following sample data:
But we want the quarters to be rows (as they should be in a normalized data model).
In Oracle or SQL Server this could be achieved with the UNPIVOT operator, but that is not available in Postgres. However Postgres’ ability to use the VALUES clause like a table makes this actually quite easy:
will return the following result:
The equivalent query with the standard UNPIVOT operator would be:
供我们这些正在寻找如何在 RedShift 中取消旋转的人参考。
Stew 给出的长格式解决方案似乎是唯一的方法完成这个。
对于那些看不到它的人,以下是粘贴的文本:
FYI for those of us looking for how to unpivot in RedShift.
The long form solution given by Stew appears to be the only way to accomplish this.
For those who cannot see it there, here is the text pasted below:
只需使用 JSON:
这会产生
dbfiddle
Just use JSON:
This yields
dbfiddle
将 @a_horse_with_no_name 评论中的链接中稍微修改的内容拉入答案,因为它有效:
安装 Hstore
如果您没有安装
hstore
并且运行的是 PostgreSQL 9.1+,则可以使用方便的CREATE EXTENSION hstore;
对于较低版本,请查找
hstore。在
文件并在数据库中运行。share/contrib
中创建 sql假设您的源(例如,宽数据)表有一个名为
id_field
的“id”列,以及任意数量的“value”列(全部类型相同),以下将创建一个非透视视图那张桌子的。这适用于任意数量的“值”列。 所有结果值都将是文本,除非您进行强制转换,例如
(h).value::numeric
。Pulling slightly modified content from the link in the comment from @a_horse_with_no_name into an answer because it works:
Installing Hstore
If you don't have
hstore
installed and are running PostgreSQL 9.1+, you can use the handyCREATE EXTENSION hstore;
For lower versions, look for the
hstore.sql
file inshare/contrib
and run in your database.Assuming that your source (e.g., wide data) table has one 'id' column, named
id_field
, and any number of 'value' columns, all of the same type, the following will create an unpivoted view of that table.This works with any number of 'value' columns. All of the resulting values will be text, unless you cast, e.g.,
(h).value::numeric
.我为 PostgreSQL 编写了一个可怕的 unpivot 函数。 它相当慢,但它至少返回像您期望的逆透视操作一样的结果。
https://cgsrv1.arrc.csiro.au /blog/2010/05/14/unpivotuncrosstab-in-postgresql/
希望你会发现它有用..
I wrote a horrible unpivot function for PostgreSQL. It's rather slow but it at least returns results like you'd expect an unpivot operation to.
https://cgsrv1.arrc.csiro.au/blog/2010/05/14/unpivotuncrosstab-in-postgresql/
Hopefully you can find it useful..
取决于你想做什么......这样的事情可能会有所帮助。
Depending on what you want to do... something like this can be helpful.
您可以使用FROM UNNEST()数组处理来UnPivot数据集,并与相关子查询串联(适用于PG 9.4)。
FROM UNNEST() 更强大且更强大。 比使用 FROM (VALUES .... ) 逆透视数据集的典型方法灵活。 这是 b/c FROM UNNEST() 是可变参数(具有 n 元数)。 通过使用相关子查询,消除了对横向 ORDINAL 子句的需要,& Postgres 将生成的并行柱状集保持在正确的顺序中。
顺便说一句,这是快速的——在实际使用中,在 <100 万行的时间内生成 800 万行。 24 核系统上为 15 秒。
结果集:
You can use FROM UNNEST() array handling to UnPivot a dataset, tandem with a correlated subquery (works w/ PG 9.4).
FROM UNNEST() is more powerful & flexible than the typical method of using FROM (VALUES .... ) to unpivot datasets. This is b/c FROM UNNEST() is variadic (with n-ary arity). By using a correlated subquery the need for the lateral ORDINAL clause is eliminated, & Postgres keeps the resulting parallel columnar sets in the proper ordinal sequence.
This is, BTW, FAST -- in practical use spawning 8 million rows in < 15 seconds on a 24-core system.
RESULT SET:
这是一种结合其他答案中的 hstore 和 CROSS JOIN 方法的方法。
这是我对类似问题的回答的修改版本,它本身基于https://blog.sql-workbench.eu/post/dynamic-unpivot/ 和 该问题的另一个答案。
与其他解决方案相比,它有一些好处:
Here's a way that combines the hstore and CROSS JOIN approaches from other answers.
It's a modified version of my answer to a similar question, which is itself based on the method at https://blog.sql-workbench.eu/post/dynamic-unpivot/ and another answer to that question.
It has a few benefits over other solutions: