PostgreSQL 如何向 regexp_split_to_table() 创建的行添加序数?

Jin*_*ska 2 postgresql

我有两张桌子。表logfile在一个属性中包含整个文本文件;表的rawtext每一行应包含文本文件中的一行文本:

create table LOGFILE ( LOGF_PK serial primary key, TEXT_CONTENT text ) ;
create table LOGTEXT ( LT_PK serial primary key, 
  LOGF_PK integer not null references LOGFILE( LOGF_PK ),
  LINENUM  integer,
  LINETEXT varchar(255)
);
Run Code Online (Sandbox Code Playgroud)

我可以将 TEXT_CONTENT 拆分为一组行,但我无法(不知道如何)在表 LOGTEXT 中生成行号,例如 LOGFILE.TEXT_CONTENT 中的第一行将位于一行 <LT_PK>、<LOGF_PK> 中, 1、‘第一行文字’等

此查询返回我期望获得的内容,但没有行号:

select LOGF_PK, regexp_split_to_table( TEXT_CONTENT, '\r?\n' ) as LINETEXT ;
Run Code Online (Sandbox Code Playgroud)

但是,我无法获得任何行号。我尝试了变体1:

select LOGF_PK
  , row_number() over (partition by LOGFILE.LOGF_PK) as LINENUM
  , regexp_split_to_table( TEXT_CONTENT, '\r?\n' )) as LINETEXT
from LOGFILE
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,LINENUM 始终为 1...

当我尝试另一种可能性时,变体 2:

select LOGF_PK
  , regexp_split_to_table( TEXT_CONTENT, '\r?\n' )) with ORDINALITY
from LOGFILE
Run Code Online (Sandbox Code Playgroud)

我收到错误

ERROR:  syntax error at or near "with"
LINE 3:   , regexp_split_to_array( content, '\r?\n' ) with ordinalit...
                                                      ^
Run Code Online (Sandbox Code Playgroud)

不幸的是,PostgreSQL 文档中很少有关于WITH ORDINALITY 的例子,而且这些例子非常笼统且无法解释。我怀疑文档中的一些示例从未在真实系统上运行过。

数据库是PostgreSQL 12.8

jka*_*lik 5

WITH ORDINALITY仅当使用生成函数代替表时才能使用,横向子查询可以允许以这种方式使用它,例如:

select
  LOGF_PK,
  LINENUM,
  LINETEXT
from LOGFILE,
lateral regexp_split_to_table( TEXT_CONTENT, '\r?\n' )
            WITH ORDINALITY as t(LINETEXT,LINENUM) ;
Run Code Online (Sandbox Code Playgroud)

另一种可能性是将row_number()调用移至外部查询:

select *, row_number() over (partition by tmp.LOGF_PK) as LINENUM
from (select LOGF_PK
  , regexp_split_to_table( TEXT_CONTENT, '\r?\n' ) as LINETEXT 
  from LOGFILE
) tmp;
Run Code Online (Sandbox Code Playgroud)

http://sqlfiddle.com/#!17/93ee4/18