Ich habe eine Datenbanktabelle (Oracle 11g) von Fragebogen-Feedback, einschließlich Multiple-Choice-, Multiple-Antwort-Fragen. Die Spalte Optionen enthält alle Werte, die der Benutzer auswählen kann, und die Spalte Antworten enthält die numerischen Werte ihrer Auswahl.SQL Regex - Ersetzen durch Teilstring aus einem anderen Feld
ID_NO OPTIONS ANSWERS
1001 Apple Pie|Banana-Split|Cream Tea 1|2
1002 Apple Pie|Banana-Split|Cream Tea 2|3
1003 Apple Pie|Banana-Split|Cream Tea 1|2|3
Ich brauche eine Abfrage, die die Antworten, mit den Textversionen der Antworten als einzelne Zeichenfolge dekodiert.
ID_NO ANSWERS ANSWER_DECODE
1001 1|2 Apple Pie|Banana-Split
1002 2|3 Banana-Split|Cream Tea
1003 1|2|3 Apple Pie|Banana-Split|Cream Tea
Ich habe mit regulären Ausdrücken experimentierte Werte zu ersetzen und Teil bekommen, aber ich kann nicht einen Weg erarbeiten, um richtig die beiden zu verschmelzen.
WITH feedback AS (
SELECT 1001 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '1|2' answers FROM DUAL UNION
SELECT 1002 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '2|3' answers FROM DUAL UNION
SELECT 1003 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '1|2|3' answers FROM DUAL)
SELECT
id_no,
options,
REGEXP_SUBSTR(options||'|', '(.)+?\|', 1, 2) second_option,
answers,
REGEXP_REPLACE(answers, '(\d)+', ' \1 ') answer_numbers,
REGEXP_REPLACE(answers, '(\d)+', REGEXP_SUBSTR(options||'|', '(.)+?\|', 1, To_Number('2'))) "???"
FROM feedback
Ich möchte die Antworten in SQL nicht manuell definieren oder dekodieren müssen; Es gibt viele Umfragen mit verschiedenen Fragen (und einer unterschiedlichen Anzahl von Optionen), also hoffe ich, dass es eine Lösung gibt, die für alle dynamisch funktioniert.
Ich habe versucht, die Optionen und Antworten in separate Zeilen nach LEVEL aufzuteilen und sie wieder zu verbinden, wo die Codes übereinstimmen, aber das läuft extrem langsam mit dem tatsächlichen Dataset (eine 5-Option-Frage mit 600 Zeilen von Antworten)).
WITH feedback AS (
SELECT 1001 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '1|2' answers FROM DUAL UNION
SELECT 1002 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '2|3' answers FROM DUAL UNION
SELECT 1003 id_no, 'Apple Pie|Banana-Split|Cream Tea' options, '1|2|3' answers FROM DUAL)
SELECT
answer_rows.id_no,
ListAgg(option_rows.answer) WITHIN GROUP(ORDER BY option_rows.lvl)
FROM
(SELECT DISTINCT
LEVEL lvl,
REGEXP_SUBSTR(options||'|', '(.)+?\|', 1, LEVEL) answer
FROM
(SELECT DISTINCT
options,
REGEXP_COUNT(options||'|', '(.)+?\|') num_choices
FROM
feedback)
CONNECT BY LEVEL <= num_choices
) option_rows
LEFT OUTER JOIN
(SELECT DISTINCT
id_no,
to_number(REGEXP_SUBSTR(answers, '(\d)+', 1, LEVEL)) answer
FROM
(SELECT DISTINCT
id_no,
answers,
To_Number(REGEXP_SUBSTR(answers, '(\d)+$')) max_answer
FROM
feedback)
WHERE
to_number(REGEXP_SUBSTR(answers, '(\d)+', 1, LEVEL)) IS NOT NULL
CONNECT BY LEVEL <= max_answer
) answer_rows
ON option_rows.lvl = answer_rows.answer
GROUP BY
answer_rows.id_no
ORDER BY
answer_rows.id_no
Wenn es keine Lösung nur mit Regex ist, ist es eine effizientere Art und Weise als LEVEL die Werte zu teilen? Oder gibt es einen anderen Ansatz, der funktionieren würde?
Relevant: http://stackoverflow.com/questions/26407538/split-string-into-rows-oracle-sql – QuestionC
Warum keine Funktion? Sollte einfacher sein. –