I took a look into the forums and couldn't really find something that I needed.
What I have is two tables one table with (Parse_Table)
File_ID|Start_Pos|Length|Description
------------------------------------
1 | 1 | 9 | Pos1
1 | 10 | 1 | Pos2
1 | 11 | 1 | Pos3
2 | 1 | 4 | Pos1
2 | 5 | 7 | Pos2
and another table that needs to be parsed like (Input_file)
String
ABCDEFGHI12
ASRQWERTQ45
123456789AB
321654852PO
and I want to have the result where If I put it will use this specific parsing spec
select DESCRIPTION, Start_pos,Length from Parse_table where File_ID=1
and be able to parse input file
String | Pos1 |Pos2|Pos3
---------------------------------
ABCDEFGHI12 |ABCDEFGHI | 1 | 2
ASRQWERTQ45 |ASRQWERTQ | 4 | 5
123456789AB |123456789 | A | B
321654852PO |321654852 | P | O
and alternatively if I put file_id=2 it would parse the values differently.
I looked at using the Pivot function, but it looks like number of columns are static, at least to my knowledge.
thanks in advance for your support please let me know what I can do in SQL.
You can get "close-ish" with the standard decode tricks to pivot the table assuming a ceiling on the maximum number of fields expected.
SQL> create table t ( fid int, st int, len int, pos varchar2(10));
Table created.
SQL>
SQL> insert into t values ( 1 , 1 , 9 , 'Pos1');
1 row created.
SQL> insert into t values ( 1 , 10 , 1 , 'Pos2');
1 row created.
SQL> insert into t values ( 1 , 11 , 1 , 'Pos3');
1 row created.
SQL> insert into t values ( 2 , 1 , 4 , 'Pos1');
1 row created.
SQL> insert into t values ( 2 , 5 , 7 , 'Pos2');
1 row created.
SQL>
SQL> create table t1 ( s varchar2(20));
Table created.
SQL>
SQL> insert into t1 values ('ABCDEFGHI12');
1 row created.
SQL> insert into t1 values ('ASRQWERTQ45');
1 row created.
SQL> insert into t1 values ('123456789AB');
1 row created.
SQL> insert into t1 values ('321654852PO');
1 row created.
SQL>
SQL>
SQL> select
2 t1.s,
3 max(decode(t.seq,1,substr(t1.s,t.st,t.len))) c1,
4 max(decode(t.seq,2,substr(t1.s,t.st,t.len))) c2,
5 max(decode(t.seq,3,substr(t1.s,t.st,t.len))) c3,
6 max(decode(t.seq,4,substr(t1.s,t.st,t.len))) c4,
7 max(decode(t.seq,5,substr(t1.s,t.st,t.len))) c5,
8 max(decode(t.seq,6,substr(t1.s,t.st,t.len))) c6
9 from t1,
10 ( select t.*, row_number() over ( partition by fid order by st ) as seq
11 from t
12 where fid = 1
13 ) t
14 group by t1.s
15 order by 1;
S C1 C2 C3 C4 C5 C6
-------------------- ------------- ------------- ------------- ------------- ------------- -------------
123456789AB 123456789 A B
321654852PO 321654852 P O
ABCDEFGHI12 ABCDEFGHI 1 2
ASRQWERTQ45 ASRQWERTQ 4 5
4 rows selected.
SQL>
SQL> select
2 t1.s,
3 max(decode(t.seq,1,substr(t1.s,t.st,t.len))) c1,
4 max(decode(t.seq,2,substr(t1.s,t.st,t.len))) c2,
5 max(decode(t.seq,3,substr(t1.s,t.st,t.len))) c3,
6 max(decode(t.seq,4,substr(t1.s,t.st,t.len))) c4,
7 max(decode(t.seq,5,substr(t1.s,t.st,t.len))) c5,
8 max(decode(t.seq,6,substr(t1.s,t.st,t.len))) c6
9 from t1,
10 ( select t.*, row_number() over ( partition by fid order by st ) as seq
11 from t
12 where fid = 2
13 ) t
14 group by t1.s
15 order by 1;
S C1 C2 C3 C4 C5 C6
-------------------- ------------- ------------- ------------- ------------- ------------- -------------
123456789AB 1234 56789AB
321654852PO 3216 54852PO
ABCDEFGHI12 ABCD EFGHI12
ASRQWERTQ45 ASRQ WERTQ45
4 rows selected.
If you really wanted that result to then come back with only the desired column count and custom column names, then you're into dynamic SQL territory. How you'd tackle that depends on the tool you are providing the data to. If it can consume a REF CURSOR, then a little PL/SQL would do the trick.
An unknown number of columns can be returned from a SQL statement, but it requires code built with PL/SQL, ANY types, and Oracle Data Cartridge.
That code is tricky to write but you can start with my open source project Method4 . Download, unzip, @install
, and then write a SQL statement to generate a SQL statement.
select * from table(method4.dynamic_query(
q'[
--Create a SQL statement to query PARSE_FILE.
select
'select '||
listagg(column_expression, ',') within group (order by start_pos) ||
' from parse_file'
column_expressions
from
(
--Create individual SUBSTR column expressions.
select
parse_table.*,
'substr(string, '||start_pos||', '||length||') '||description column_expression
from parse_table
--CHANGE BELOW LINE TO USE A DIFFERENT FILE:
where file_id = 2
order by start_pos
)
]'
));
create table parse_table as
select 1 file_id, 1 start_pos, 9 length, 'Pos1' description from dual union all
select 1 file_id, 10 start_pos, 1 length, 'Pos2' description from dual union all
select 1 file_id, 11 start_pos, 1 length, 'Pos3' description from dual union all
select 2 file_id, 1 start_pos, 4 length, 'Pos1' description from dual union all
select 2 file_id, 5 start_pos, 7 length, 'Pos2' description from dual;
create table parse_file as
select 'ABCDEFGHI12' string from dual union all
select 'ASRQWERTQ45' string from dual union all
select '123456789AB' string from dual union all
select '321654852PO' string from dual;
When FILE_ID = 1
:
POS1 POS2 POS3
---- ---- ----
ABCDEFGHI 1 2
ASRQWERTQ 4 5
123456789 A B
321654852 P O
When FILE_ID = 2
:
POS1 POS2
---- ----
ABCD EFGHI12
ASRQ WERTQ45
1234 56789AB
3216 54852PO
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.