Back Story

我有一个Employee表,其中每个员工都分配了一个或多个工作角色,对于每个分配的角色,它都显示了分配的年份.我有一个查询,它构建一个矩阵表格,每个员工一行,如下所示:

name role1 role2 role3 role4 role5
Bunny, Bugs 2022
Coyote, Wiley 2018 2018
Pig, Porky 2017
Mouse, Mickey 2020
Panther, Pink 2019
Cheese, Chuckey 2021 2017
Duck, Donald 2021 2021
Devil, Taz 2019
Brown, Charlie 2021 2019
Flintstone, Fred 2019 2011 2016

Summary Columns

我需要一些额外的列,这些列 for each 员工计算以下内容:

  1. 分配给员工的角色数(计数?)
  2. 分配的最早角色的年份(最少)
  3. 最近分配的角色所在的年份(最大)

Desired Results

此表说明了我的分析所需的结果:

name role1 role2 role3 role4 role5 role_count role_oldest role_newest
Bunny, Bugs 2022 1 2022 2022
Coyote, Wiley 2018 2015 2 2015 2018
Pig, Porky 2017 1 2017 2017
Mouse, Mickey 2020 1 2020 2020
Panther, Pink 2019 1 2019 2019
Cheese, Chuckey 2021 2017 2 2017 2021
Duck, Donald 2021 2021 2 2021 2021
Devil, Taz 2019 1 2019 2019
Brown, Charlie 2021 2019 2 2019 2021
Flintstone, Fred 2019 2011 2016 3 2016 2019

My Mixed Results

对于第role_oldest列和第role_newest列,我可以使用以下语句:

UPDATE employee_roles
  SET role_oldest = LEAST(role1, role2, role3, role4, role5);

UPDATE employee_roles
  SET role_newest = GREATEST(role1, role2, role3, role4, role5);

然而,在迭代try 计算Role_count时,我try 了COUNTARRAYUNNESTSTRING_TO_ARRAY函数的各种组合,但没有成功,如下所示:

UPDATE employee_roles
  SET role_count = COUNT(role1, role2, role3, role4, role5);
UPDATE employee_roles
  SET role_count = COUNT(UNNEST(role1, role2, role3, role4, role5));
UPDATE employee_roles
  SET role_count = COUNT(UNNEST(ARRAY(role1, role2, role3, role4, role5)));
UPDATE employee_roles
  SET role_count = COUNT(UNNEST(ARRAY(STRING_TO_ARRAY(role1, role2, role3, role4, role5))));

Climbing Out of the Rabbit Hole

很明显,我在这个练习中走错了路,所以我退出了,并在这方面寻求您的帮助.我相信确实有一个优雅的解决方案,它就在我的眼皮底下,我希望有人能帮我找到它.

Similar Questions with Complicated Answers

我在so上找到了许多其他类似的帖子,每个帖子都包含需要大量PSQL体操的疯狂解决方案,我发现很难相信没有一个简单的函数可以做到这一点.

Code for Creating Sample Table

以下代码块将帮助您快速创建本练习的示例表:

create table employee_roles
(
    name        text,
    role1       integer default null,
    role2       integer default null,
    role3       integer default null,
    role4       integer default null,
    role5       integer default null,
    role6       integer default null,
    role_count  integer default null,
    role_oldest integer default null,
    role_newest integer default null
);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Bunny, Bugs',null,null,null,null,2022);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Coyote, Wiley',2018,null,null,2018,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Pig, Porky',null,null,2017,null,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Mouse, Mickey',null,null,null,2020,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Panther, Pink',2019,null,null,null,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Cheese, Chuckey',null,null,2021,2017,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Duck, Donald',2021,null,null,2021,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Devil, Taz',null,2019,null,null,null);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Brown, Charlie',null,null,2021,null,2019);
insert into employee_roles (name,role1,role2,role3,role4,role5)
    values ('Flintstone, Fred',2019,null,2011,2016,null);

推荐答案

我不确定您使用的是哪个版本(您可以更新吗?)--在v14中,它看起来不像GREATEST()LEAST()按照您所描述的那样运行.

您可以try 执行以下操作以获得您想要的COUNT输出:

edb=# select name, array_length(array_remove(array[role1,role2,role3,role4,role5],null),1) from employee_roles ;
       name       | array_length                                                                                
------------------+--------------                                                                               
 Bunny, Bugs      |            1                                                                                
 Coyote, Wiley    |            2                                                                                
 Pig, Porky       |            1                                                                                
 Mouse, Mickey    |            1                                                                                
 Panther, Pink    |            1                                                                                
 Cheese, Chuckey  |            2                                                                                
 Duck, Donald     |            2                                                                                
 Devil, Taz       |            1                                                                                
 Brown, Charlie   |            2                                                                                
 Flintstone, Fred |            3                                                                                
(10 rows)                                                                                                       

Postgresql相关问答推荐

当通过PostgreSQL FDW中的视图使用时,年龄函数的计算方式不同

带有regex表达式的Postgres SQL

读取扩展坞合成中的UDP:IO/超时

使用PGx在围棋中执行多条SQL语句

在Haskell中定义新类型与持久化类型的惯用方法

Postgres SQL:获取列值在连续日期之间已更改的行

使用 pgx 扫描范围类型

求和直到达到一个值 postgresql

如何使用 SQLAlchemy 将列默认设置为 PostgreSQL 函数?

函数将多列作为单列而不是多列返回

是否可以在 PostgreSQL 中部分刷新materialized视图?

如何在 postgres json 列中查询嵌套数组?

使用 RPostgreSQL 写入特定模式

PostgreSQL 中跨多个表的索引

PostgreSQL 字符串(255) 限制 - Rails、Ruby 和 Heroku

避免通过 JPA 将null值插入数据库表

pg_restore 会覆盖现有的表吗?

使用 PostgreSQL 进行字母数字排序

错误:无法在只读事务中执行 CREATE TABLE

将postgres中的所有记录转换为Titlecase,首字母大写