One Row to Multiple Rows – Case 4
【Question】
Here’s a table:
StudentID Course
1 Chinese,Maths,English
2 Humanities,History,Geography
3 Geography,Chinese
4 Geography,Maths
I need to split the course records into this by StudentID:
1 Chinese
1 Maths
1 English
2 Humanities
2 History
2 Geography
4 Geography
4 Maths
3 Geography
3 Chinese
【Answer】
With Oracle, you can use hierarchical queries having subqueries or random numbers to handle this. Here’re two solutions:
Solution 1:
SELECT StudentID,REGEXP_SUBSTR(Course,'\[^,\]+',1,rn) Course
FROM t0052,
(SELECT LEVEL rn
FROM DUAL
CONNECT BY LEVEL<=(SELECT
MAX(length(trim(translate(Course,replace(Course,','),' '))))+1
FROM t0052))
WHERE REGEXP_SUBSTR(Course,'\[^,\]+',1,rn) IS NOT NULL
Solution 2:
select StudentID,regexp_substr(Course,'\[^,\]+',1,level) Course
from t0052
connect by level <= (length(Course)-length(regexp_replace(Course,'\[^,\]+','')))
and rowid= prior rowid
and prior dbms_random.value is not null;
Oracle hacks are used in both solutions (such as “prior dbms_random.value is not null” for avoiding loop errors). This requires that users should have some Oracle skills). And the program becomes unexecutable in a different database product. Here’s a universal solution written in SPL (Structured Process Language):
A |
|
1 |
$SELECT StudentID,Course FROM t0052 |
2 |
=A1.news(Course.array();StudentID,~:Course) |
The script is simple and concise. Below is A2’s result:
StudentID |
Course |
1 |
Chinese |
1 |
Maths |
1 |
English |
2 |
Humanities |
2 |
History |
2 |
Geography |
3 |
Geography |
3 |
Chinese |
4 |
Geography |
4 |
Maths |
esProc offers JDBC interface to be conveniently embedded into a Java application. See How to Call an SPL Script in Java.
SPL Official Website 👉 https://www.scudata.com
SPL Feedback and Help 👉 https://www.reddit.com/r/esProcSPL
SPL Learning Material 👉 https://c.scudata.com
SPL Source Code and Package 👉 https://github.com/SPLWare/esProc
Discord 👉 https://discord.gg/cFTcUNs7
Youtube 👉 https://www.youtube.com/@esProc_SPL