从数字字符串中生成行
我有一个具有这样的字符串的Oracle 18C表:
select
'((0 5 0, 10 10 11.18, 30 0 33.54),(50 10 33.54, 60 10 43.54))' as multipart_lines
--There are more rows in the actual table.
from
dual
MULTIPART_LINES
-------------------------------------------------------------
((0 5 0, 10 10 11.18, 30 0 33.54),(50 10 33.54, 60 10 43.54))
-- v1 v2 v3 v4 v5
-- | part 1 | | part 2 |
- 单个坐标被空间分开。
- 顶点(XYZ坐标)通过逗号分隔。
- 线零件用括号包裹,并用逗号分隔。
在查询中,我想为每个顶点生成行:
PART_NUM VERTEX_NUM X Y Z
---------- ---------- ---------- ---------- ----------
1 1 0 5 0
1 2 10 10 11.18
1 3 30 0 33.54
2 1 50 10 33.54
2 2 60 10 43.54
- 我想在查询中执行此操作。我不想将行插入表中。
- 不幸的是,我没有在数据库中创建类型特权。但是我 can 创建函数(当然,内联函数也是一个选项)。
如何从字符串中的数字(顶点)产生行?
相关: oracle构思 - generate_serate_serate_serate_series(generate_serate_series function )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
另外 - 您可以如何处理输入字符串将其转换为适当的JSON字符串;然后任务变得微不足道。首先仅显示JSON-IAGIAD,因为它确实是该解决方案的有意义的部分。然后,在显示查询和结果后,我将通过添加JSON操作来完成解决方案。
您的输入确实应该看起来像我的子查询
J
中的列中的字符串 - 然后您可以这样处理它们:输出与我的其他答案相同。
As an alternative - here is how you can process the input strings to convert them to proper JSON strings; then the task becomes trivial. Showing just the JSON-ization first, separately, as it really is the meaningful part of this solution; then after I show the query and result, I will complete the solution by adding the JSON manipulation.
Your inputs should really look like the strings in column
ml
in my subqueryj
- then you could process them like this:The output is the same as in my other answer.
如果输入以某种标准格式(例如JSON),则将更简单。那么任务将是微不足道的。您对此有任何权力吗?
如果没有,您可以将输入转换为适当的JSON(或类似),也可以直接攻击问题。我说明了下面的后者,假设Oracle版本12.1或更高版本。
输出(来自我在查询中包含的样本输入):
It would be so much simpler if the input was in some standard format - for example JSON. Then the task would be trivial. Do you have any power over that?
If not, you could either transform the input into proper JSON (or similar), or you could attack the problem directly. I illustrate the latter below, assuming Oracle version 12.1 or higher.
Output (from the sample inputs I included in the query):
我看到Mathguy到了那里。我正在使用JSON_TABLE 的
工作,但是我无法一次解开2行,否则我基本上会在那里第二次使用row_number()over(通过paru_num划分)。
1行影响
db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
) ), d as(( 选择'[“'|| pn ||' '||。 ) 从D中选择 *db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
) ), d as(( 选择'[“'|| pn ||' '||。 ), e( 选择 row_number()over(按'Zero'订购)pn, 值c 来自json_table(((从d中选择D),'$ [*]' 列(值路径'db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
) ), d as(( 选择'[“'|| pn ||' '||。 ) 从D中选择 *db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
) )) 从E中选择 *db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
) ), d as(( 选择'[“'|| pn ||' '||。 ) 从D中选择 *db<>>
) ) ), d as(( 选择 光盘, 仪器(c,'')s1, 仪器(c,'',inst(c,'')+1)s2 来自C) 选择 substr(d,0,s1)x, substr(d,s1+1,s2-s1)y, substr(d,s2+1)z 从ddb<>>
I see that mathguy has got there. I was working with
from json_table
but I can't unnest 2 rows at a time otherwise I'd be basically there with a second use of row_number() over (partition by Paru_num).1 rows affected
db<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
) ) ), d as ( select '["'|| pn ||' '|| regexp_replace(c,', ?','","'||pn||' ')||'"]' d from c ) select * from ddb<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
) ) ), d as ( select '["'|| pn ||' '|| regexp_replace(c,', ?','","'||pn||' ')||'"]' d from c ), e as ( SELECT row_number() over (order by 'zero') pn, value c FROM json_table( (select d from d) , '$[*]' COLUMNS (value PATH 'db<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
) ) ), d as ( select '["'|| pn ||' '|| regexp_replace(c,', ?','","'||pn||' ')||'"]' d from c ) select * from ddb<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
) ) ) select * from edb<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
) ) ), d as ( select '["'|| pn ||' '|| regexp_replace(c,', ?','","'||pn||' ')||'"]' d from c ) select * from ddb<>fiddle here
) ) ), d as ( SELECT c d, instr(c,' ') s1, instr(c,' ',instr(c,' ')+1) s2 from c) select substr(d,0,s1) x, substr(d,s1+1,s2-s1) y, substr(d,s2+1) z from ddb<>fiddle here
您只能使用简单的字符串函数(比正则表达式快得多)和递归子征出来来完成此操作:
对于示例数据:输出:
输出:
db&lt;&gt; fiddle 此处
You can do it with only simple string functions (which are much faster than regular expressions) and recursive sub-queries:
Which, for the sample data:
Outputs:
db<>fiddle here
使用
sdo_geometry
来解析字符串,然后使用sdo_util.extract
获取每个元素,然后sdo_util.getvertices
获取顶点:对于哪个元素:示例数据:
输出:
db&lt;&gt; fiddle 此处
Use
SDO_GEOMETRY
to parse the string and then useSDO_UTIL.EXTRACT
to get each element and thenSDO_UTIL.GETVERTICES
to get the vertices:Which, for the sample data:
Outputs:
db<>fiddle here
@solomonyakobson在
以及Oracle 19c解决方案:
@SolomonYakobson provided this answer in an Oracle Community post.
As well as an Oracle 19c solution: