Postgres - 动态生成多行和多列并加入现有的 table

Postgres - generate multiple rows and columns dynamically and join to an existing table

我正在尝试将 oracle 查询转换为 postgres。

Oracle 查询使用以下生成动态 table 类数据:

SELECT ROWNUM TYPE_ID, regexp_substr('NED,SED,ZED,MED', '[^,]+', 1, LEVEL) TYPE
FROM DUAL
CONNECT BY regexp_substr('NED,SED,ZED,MED', '[^,]+', 1, LEVEL) IS NOT NULL

Output:
TYPE_ID,TYPE
1,NED
2,SED
3,ZED
4,MED

考虑样本 table:

create table details(
Title Varchar,
Misc Varchar
);

insert into details values ('DBA','5 years');

这是整个查询:

select /*ACC DATA*/ (case when ACC.TYPE_ID= 4 then null else
Title end)  Job_title,
ACC.* from DUAL,
(SELECT ROWNUM TYPE_ID, regexp_substr('NED,SED,ZED,MED', '[^,]+', 1, LEVEL) TYPE
FROM DUAL
CONNECT BY regexp_substr('NED,SED,ZED,MED', '[^,]+', 1, LEVEL) IS NOT NULL) ACC,
details

Output looks like this:
JOB_TITLE,TYPE_ID,TYPE
DBA,1,NED
DBA,2,SED
DBA,3,ZED

如此有效,查询将详细信息 table 的每一行返回三次,其中 TYPE_ID 分别为 1、2、3,TYPE 分别为 NED、SED、ZED。

如何在 Postgres 11.5 中实现这一点?

如您所见,Postres 没有有用的 "connect by ..."。但它确实有其他同样有用的功能。在这种情况下:(参见 fiddle

两者都会将字符串解析为单个元素。不幸的是,它们都没有提供枚举,但是,它很容易从窗口函数 row_number 中获得。因此,您的 Oracle 语句变为(type 是 Postgres 中的保留字,会产生错误,因此我更改为 type_val。)

select row_number() over() type_id,type_val 
  from (select unnest(string_to_array('NED,SED,ZED,MED',',')) type_val ) sl 

有了它,只需一个简单的步骤就可以将它与您的详细信息进行交叉连接 table 得到您想要的。

with split_list(type_id,type_val) as
     ( select row_number() over() type_id,type_val 
         from (select unnest(string_to_array('NED,SED,ZED,MED',',')) type_val ) sl 
     )         
select title, type_id, type_val
  from details
 cross join split_list
 where type_id != 4;