postgresql行转列、列转行

列转行

postgresql列转行的思路主要是利用string_to_array进行数组转换,然后用unnest进行行拆分
在这里插入图片描述

select t.bid_unit,unit_id from unit t
where t.unit_id=1947;

result=> 中国信息通信研究院;北京市海淀区学院

-- by zhengkai.blog.csdn.net

在这里插入图片描述

select unnest(string_to_array(t.bid_unit,';')),unit_id from unit t
where t.unit_id=1947;

result=> 
中国信息通信研究院
北京市海淀区学院

-- by zhengkai.blog.csdn.net

pgsql官方对functions-array的解释

FunctionReturn TypeDescriptionExampleResult
string_to_array(text, text [, text])text[]splits string into array elements using supplied delimiter and optional null string (使用提供的分隔符和可选的空字符串将字符串分割为数组元素)string_to_array(‘xx^yy^zz’, ‘^’, ‘yy’){xx,NULL,zz}
unnest(anyarray)setof anyelementexpand an array to a set of rows(将数组展开到一组行)unnest(ARRAY[1,2])1 2 (2 rows)

行转列

用postgresql的crosstab交叉函数

-- by zhengkai.blog.csdn.net
create table sales(year int, month int, qty int);
insert into sales values(2022, 1, 1000);
insert into sales values(2022, 2, 1500);
insert into sales values(2022, 7, 500);
insert into sales values(2022, 11, 1500);
insert into sales values(2022, 12, 2000);
insert into sales values(2023, 1, 1200);

select * from crosstab(
  'select year, month, qty from sales order by 1',
  'select m from generate_series(1,12) m'
) as (
  year int,
  "Jan" int,
  "Feb" int,
  "Mar" int,
  "Apr" int,
  "May" int,
  "Jun" int,
  "Jul" int,
  "Aug" int,
  "Sep" int,
  "Oct" int,
  "Nov" int,
  "Dec" int
);
 year | Jan  | Feb  | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov  | Dec
------+------+------+-----+-----+-----+-----+-----+-----+-----+-----+------+------
 2022 | 1000 | 1500 |     |     |     |     | 500 |     |     |     | 1500 | 2000
 2023 | 1200 |      |     |     |     |     |     |     |     |     |      |
(2 rows)

可以参考pgsql官方的tablefunc实用说明

FunctionReturnsDescription
normal_rand(int numvals, float8 mean, float8 stddev)setof float8Produces a set of normally distributed random values(产生一组正态分布的随机值)
crosstab(text sql)setof recordProduces a “pivot table” containing row names plus N value columns, where N is determined by the row type specified in the calling query(生成一个包含行名和N个值列的“数据透视表”,其中N个由调用查询中指定的行类型决定)
crosstabN(text sql)setof table_crosstab_NProduces a “pivot table” containing row names plus N value columns. crosstab2, crosstab3, and crosstab4 are predefined, but you can create additional crosstabN functions as described below(生成一个包含行名和N个值列的“数据透视表”。交叉表2、交叉表3和交叉表4都是预定义的,但是您可以创建额外的跨表n函数,如下面所述)
crosstab(text source_sql, text category_sql)setof recordProduces a “pivot table” with the value columns specified by a second query(生成具有由第二个查询指定的值列的“数据透视表”)
crosstab(text sql, int N)setof recordObsolete version of crosstab(text). The parameter N is now ignored, since the number of value columns is always determined by the calling query(过时版本的交叉表(文本)。参数N现在被忽略,因为值列的数量总是由调用查询决定)
connectby(text relname, text keyid_fld, text parent_keyid_fld [, text orderby_fld ], text start_with, int max_depth [, text branch_delim ])setof recordProduces a representation of a hierarchical tree structure(生成层次树结构的表示)
### 回答1: 在 PostgreSQL 中,可以使用 crosstab 函数将行数据转换为列数据。crosstab 函数需要安装 tablefunc 扩展,可以使用以下命令安装: ``` CREATE EXTENSION IF NOT EXISTS tablefunc; ``` 假设有以下原始表格: ``` CREATE TABLE sales ( id SERIAL PRIMARY KEY, month TEXT, product TEXT, amount INTEGER ); INSERT INTO sales (month, product, amount) VALUES ('Jan', 'Product A', 100), ('Jan', 'Product B', 200), ('Feb', 'Product A', 150), ('Feb', 'Product B', 250); ``` 使用 crosstab 函数将行数据转换为列数据: ``` SELECT * FROM crosstab( 'SELECT month, product, amount FROM sales ORDER BY 1,2', 'SELECT DISTINCT product FROM sales ORDER BY 1' ) AS final_result (month TEXT, product_a INTEGER, product_b INTEGER); ``` 上面的查询将返回以下结果: ``` month | product_a | product_b -------+-----------+----------- Feb | 150 | 250 Jan | 100 | 200 ``` 在 crosstab 函数中,第一个参数指定了原始查询语句,第二个参数指定了列名。在上面的例子中,我们使用 DISTINCT 关键字获取唯一的产品列表,并将其用作列名。在返回结果中,每个月份和每个产品都有一个对应的列。 ### 回答2: PostgreSQL是一种强大的开源关系型数据库管理系统,提供了许多丰富的功能来处理数据。在PostgreSQL中进行行转列操作可以通过使用UNPIVOT和PIVOT两种方法来实现。 对于行转列操作,可以使用UNPIVOT语句将多列转换为单列。例如,如果有一个包含不同课程成绩的表,列名称为课程名,行为不同学生的成绩,可以使用UNPIVOT将列转换为行。语法如下: ```sql SELECT student_id, course_name, score FROM grades UNPIVOT (score FOR course_name IN (math, english, science)) AS unpvt; ``` 这将返回一个包含学生ID、课程名和成绩的结果集。UNPIVOT语句通过将列名称和对应的值组合为单个行来进行行转列。 另一种方法是使用PIVOT语句进行行转列操作。PIVOT实际上是对UNPIVOT的逆操作,它将单列转换为多列。例如,如果有一个包含学生ID、课程名和成绩的表,可以使用PIVOT将课程名作为列名称,并将成绩作为对应的值进行行转列。语法如下: ```sql SELECT * FROM grades PIVOT ( MAX(score) FOR course_name IN (math, english, science) ) AS pvt; ``` 这将返回一个包含学生ID、数学成绩、英语成绩和科学成绩的结果集。PIVOT语句通过指定聚合函数(如MAX)和需要转换的列名称来进行行转列操作。 无论是使用UNPIVOT还是PIVOT,PostgreSQL提供了灵活的工具来进行行转列操作,便于根据需要重新组织和处理数据。 ### 回答3: PostgreSQL本身并没有提供直接的行转列功能,但可以使用一些技巧来实现行转列的效果。 首先,我们可以使用UNION ALL将多个查询结果合并为一个结果集,每个查询结果表示一列的值。例如,我们有一个表格是以行的形式存储了不同人员的年龄信息,我们希望将每个人的年龄转换为列,可以使用以下语句: SELECT p.name, p.age FROM ( SELECT 'Alice' AS name, age_1 AS age FROM person UNION ALL SELECT 'Bob' AS name, age_2 AS age FROM person UNION ALL SELECT 'Charlie' AS name, age_3 AS age FROM person ) AS p; 以上语句中,首先对person表进行了三个子查询,通过UNION ALL将结果合并为一个结果集。每个子查询表示了一个人的年龄信息,并在结果中使用了别名name和age。最终将结果作为子查询p,进行外部查询,得到每个人的姓名和年龄的行转列结果。 如果希望自动化完成行转列的操作,可以使用PL/pgSQL编写存储过程。在存储过程中,可以使用动态SQL来生成行转列的查询语句,并执行。 总之,尽管PostgreSQL本身没有提供行转列的直接功能,但可以通过UNION ALL和PL/pgSQL等技巧来实现行转列的效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值