Sql 用于在均匀分布的多行中获取单行输出的正则表达式

Sql 用于在均匀分布的多行中获取单行输出的正则表达式,sql,oracle,Sql,Oracle,我已将输出格式化为单行,采用管道分隔格式,如 chq编号、金额、受益人名称 e、 g: 我希望输出的格式基于记录数。如果我的查询返回50个管道分隔值,请参见下面的sql,那么我希望输出平均分布在5行中,每行10条记录,依此类推 123,100.00,test1 | 234,200.00,test2 | 345,300.00,test4 111,100.00,test5 | 222,200.00,test6 | 333,300.00,test7 444,100.00,test3 | 555,20

我已将输出格式化为单行,采用管道分隔格式,如 chq编号、金额、受益人名称 e、 g:

我希望输出的格式基于记录数。如果我的查询返回50个管道分隔值,请参见下面的sql,那么我希望输出平均分布在5行中,每行10条记录,依此类推

123,100.00,test1 | 234,200.00,test2 | 345,300.00,test4 
111,100.00,test5 | 222,200.00,test6 | 333,300.00,test7
444,100.00,test3 | 555,200.00,test9 | 666,300.00,test8
我测试了一个查询,但输出并不像预期的那样

WITH w AS (
select count(*), ACCOUNTNO, rtrim (xmlagg (xmlelement (a,info || ' | ')).extract ('//text()'), ',')  info1
from (
select ACCOUNTNO, CHECKNO || ' , ' || AMOUNT || ' , ' || BENE_NAME info from test_alert_log
where trunc(TXNDATE) = '30-NOV-2015' and trim(ACCOUNTNO) = '1234567890'
)
group by ACCOUNTNO)

SELECT regexp_substr(info1,'[^|]+', 1, column_value)
  FROM w,
       TABLE(
         CAST(
           MULTISET(SELECT LEVEL 
                       FROM dual  
                    CONNECT BY LEVEL <= LENGTH(info1) + LENGTH(replace(info1, '|')) + 1
                   ) AS sys.OdciNumberList
         )
       )
WHERE regexp_substr(info1,'[^|]+', 1, column_value) IS NOT NULL 

我相信这会成功的。从第14行开始,connectby首先计算分隔符并加1得到字段数,然后除以2得到我的示例中每行所需的记录数,然后通过CEIL运行,CEIL基本上会四舍五入处理部分行(如果有)

然后查看第7行,其中它输出列_value-eth。实际上,模式的行eth引用至少为1,但不超过2必须等于前面段落中0个或多个字符的模式中的2,这些字符不是管道,后跟分隔符或行尾。它是贪婪的,所以如果它们可用,它将抓取2个。后面的空格/pipe/space在正则表达式中没有lookahead,必须从输出中删除,所以我只使用rtrim。输出周围的方括号仅用于说明不存在空格,当然应在生产时删除

SQL> with w(info1) as (
  2    select '123,100.00,test1 | 234,200.00,test2 | 345,300.00,test3 | 111,100.00,test4 | ' ||
  3           '222,200.00,test5 | 333,300.00,test6 | 444,100.00,test7 | 555,200.00,test8 | ' ||
  4           '666,300.00,test9' from dual
  5  )
  6  SELECT column_value, '[' ||
  7         rtrim(regexp_substr(info1, '(([^|]*( \| |$)){1,2})', 1, column_value, NULL, 1), ' | ') ||
  8         ']' output
  9  FROM w,
 10       TABLE(
 11         CAST(
 12           MULTISET(SELECT LEVEL
 13                    FROM dual
 14                    CONNECT BY LEVEL <= ceil((REGEXP_COUNT(info1, ' \| ') + 1) / 2) -- Calculates rows
 15                   ) AS sys.OdciNumberList
 16             )
 17            );

COLUMN_VALUE OUTPUT
------------ ----------------------------------------
           1 [123,100.00,test1 | 234,200.00,test2]
           2 [345,300.00,test3 | 111,100.00,test4]
           3 [222,200.00,test5 | 333,300.00,test6]
           4 [444,100.00,test7 | 555,200.00,test8]
           5 [666,300.00,test9]

SQL>

因此,第7行和第14行中的数字2只需更改为您希望在一行中显示的记录数,这对您来说应该很好。让我们知道它是如何工作的。

使用查询的输出更新您的帖子,精确显示输出如何不符合预期。进一步分析后,我发现这会在一列中打印您的记录,是吗?没有一个地方可以尝试在一行上打印多个记录,所以我怀疑这就是问题所在。计算一行打印多少条记录的公式是什么?如果有奇数条记录怎么办?只是在编写解决方案之前需要考虑的问题。哦,用下面的话来简化连线:按级别连线嗨,加里,你是对的。如前所述,我首先格式化单行123100.00、test1 | 234200.00、test2 | 345300.00、test4中的数据。。。。。。。。。N然后,我试图获得所选记录的预期行输出,比如说,如果我有50条管道分隔的记录,那么我希望将该字符串拆分为相等数量的行,因为在本例中,将有5行,每个行包含10条记录。因此,只需将记录分成多行即可。希望这能澄清。谢谢
SQL> with w(info1) as (
  2    select '123,100.00,test1 | 234,200.00,test2 | 345,300.00,test3 | 111,100.00,test4 | ' ||
  3           '222,200.00,test5 | 333,300.00,test6 | 444,100.00,test7 | 555,200.00,test8 | ' ||
  4           '666,300.00,test9' from dual
  5  )
  6  SELECT column_value, '[' ||
  7         rtrim(regexp_substr(info1, '(([^|]*( \| |$)){1,2})', 1, column_value, NULL, 1), ' | ') ||
  8         ']' output
  9  FROM w,
 10       TABLE(
 11         CAST(
 12           MULTISET(SELECT LEVEL
 13                    FROM dual
 14                    CONNECT BY LEVEL <= ceil((REGEXP_COUNT(info1, ' \| ') + 1) / 2) -- Calculates rows
 15                   ) AS sys.OdciNumberList
 16             )
 17            );

COLUMN_VALUE OUTPUT
------------ ----------------------------------------
           1 [123,100.00,test1 | 234,200.00,test2]
           2 [345,300.00,test3 | 111,100.00,test4]
           3 [222,200.00,test5 | 333,300.00,test6]
           4 [444,100.00,test7 | 555,200.00,test8]
           5 [666,300.00,test9]

SQL>