Sql 用于在均匀分布的多行中获取单行输出的正则表达式
我已将输出格式化为单行,采用管道分隔格式,如 chq编号、金额、受益人名称 e、 g: 我希望输出的格式基于记录数。如果我的查询返回50个管道分隔值,请参见下面的sql,那么我希望输出平均分布在5行中,每行10条记录,依此类推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
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>