split_part separar regexp_substr parse hacer español ejemplos cadena array sql regex oracle split

sql - separar - oráculo: divide varios valores separados por comas en la tabla de oráculo en varias filas



separar cadena oracle (6)

Prueba así,

WITH CTE AS (SELECT ''a,b,c,d,e'' temp,1 slno FROM DUAL UNION SELECT ''f,g'',2 from dual UNION SELECT ''h'',3 FROM DUAL) SELECT regexp_substr (temp, ''[^,]+'', 1, rn)temp, slno FROM cte CROSS JOIN ( SELECT ROWNUM rn FROM (SELECT MAX (LENGTH (regexp_replace (temp, ''[^,]+''))) + 1 max_l from cte ) connect by level <= max_l ) WHERE regexp_substr (temp, ''[^,]+'', 1, rn) IS NOT NULL order by temp;

Tengo un problema con la consulta dividida de Oracle.

Al dividir los datos separados por comas en varias filas usando connect by y la expresión regular en la consulta de Oracle, obtengo más filas duplicadas . por ejemplo, en realidad, mi tabla tiene 150 filas en esa dos filas que tienen cadenas separadas por comas, así que en general tengo que obtener solo 155 filas pero obtengo 2000 filas. Si utilizo distinct funciona bien, pero no quiero filas duplicadas en el resultado de la consulta.

Intenté la siguiente consulta, pero está generando filas duplicadas en el resultado de la consulta:

WITH CTE AS (SELECT ''a,b,c,d,e'' temp,1 slno FROM DUAL UNION SELECT ''f,g'',2 from dual UNION SELECT ''h'',3 FROM DUAL) SELECT TRIM(REGEXP_SUBSTR( TEMP, ''[^,]+'', 1, LEVEL)) ,SLNO FROM CTE CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(temp, ''[^,]+'')) + 1

EDITAR

La consulta de selección anterior solo puede dividir una sola cadena delimitada por comas , sin embargo, produce filas duplicadas cuando se ejecuta en una tabla con varias filas . ¿Cómo restringir las filas duplicadas?


Puede usar la consulta siguiente para convertir valores separados por comas en filas

SELECT trim(x.column_value.extract(''e/text()'')) COLUMNS from t t, table (xmlsequence(xmltype(''<e><e>'' || replace(valuestring,'':'',''</e><e>'')|| ''</e></e>'').extract(''e/e''))) x );


sin usar connect by :

WITH CTE AS (SELECT ''a,b,c,d,e'' temp,1 slno FROM DUAL UNION SELECT ''f,g'',2 from dual UNION SELECT ''h'',3 FROM DUAL ) ,x as ( select '',''||temp||'','' temp ,slno from CTE ) ,iter as (SELECT rownum AS pos FROM all_objects ) select SUBSTR(x.temp ,INSTR(x.temp, '','', 1, iter.pos) + 1 ,INSTR(x.temp, '','', 1, iter.pos + 1)-INSTR(x.temp, '','', 1, iter.pos)-1 ) temp ,x.slno from x, iter where iter.pos < = (LENGTH(x.temp) - LENGTH(REPLACE(x.temp, '',''))) - 1;


La respuesta aceptada usa la condición DBMS_RANDOM.VALUE IS NOT NULL que es inapropiada. Simplemente evita el ciclo cíclico, sin embargo, surgiría una pregunta directa como ¿Cómo y cuándo dbms_random.VALUE puede ser nulo? Lógicamente, nunca será NULL .

La solución más adecuada es usar sys.odciNumberList y evitar el ciclo cíclico.

Por ejemplo,

Preparar

SQL> CREATE TABLE t ( 2 ID NUMBER GENERATED ALWAYS AS IDENTITY, 3 text VARCHAR2(100) 4 ); Table created. SQL> SQL> INSERT INTO t (text) VALUES (''word1, word2, word3''); 1 row created. SQL> INSERT INTO t (text) VALUES (''word4, word5, word6''); 1 row created. SQL> INSERT INTO t (text) VALUES (''word7, word8, word9''); 1 row created. SQL> COMMIT; Commit complete. SQL> SQL> SELECT * FROM t; ID TEXT ---------- ---------------------------------------------- 1 word1, word2, word3 2 word4, word5, word6 3 word7, word8, word9 SQL>

Consulta obligatoria:

SQL> SELECT t.id, 2 trim(regexp_substr(t.text, ''[^,]+'', 1, lines.column_value)) text 3 FROM t, 4 TABLE (CAST (MULTISET 5 (SELECT LEVEL FROM dual CONNECT BY LEVEL <= regexp_count(t.text, '','')+1) 6 AS sys.odciNumberList 7 ) 8 ) lines 9 ORDER BY id 10 / ID TEXT ---------- -------------------------------------------------- 1 word1 1 word2 1 word3 2 word4 2 word5 2 word6 3 word7 3 word8 3 word9 9 rows selected.

Una solución alternativa usando XMLTABLE :

SQL> SELECT id, 2 trim(COLUMN_VALUE) text 3 FROM t, 4 xmltable((''"'' 5 || REPLACE(text, '','', ''","'') 6 || ''"'')) 7 / ID TEXT ---------- ------------------------ 1 word1 1 word2 1 word3 2 word4 2 word5 2 word6 3 word7 3 word8 3 word9 9 rows selected. SQL>

Hay muchas maneras de lograr la tarea, como una cláusula MODELO . Para ver más ejemplos, vea Separar cadenas delimitadas por comas en una tabla


Finalmente, se me ocurrió esta respuesta

WITH CTE AS (SELECT ''a,b,c,d,e'' temp, 1 slno FROM DUAL UNION SELECT ''f,g'' temp, 2 slno FROM DUAL UNION SELECT ''h'' temp, 3 slno FROM DUAL) SELECT TRIM(REGEXP_SUBSTR(temp, ''[^,]+'', 1, level)), slno FROM CTE CONNECT BY level <= REGEXP_COUNT(temp, ''[^,]+'') AND PRIOR slno = slno AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL


Agregar una cláusula única hace el truco:

WITH cte AS ( SELECT ''a,b,c,d,e'' temp, 1 slno FROM DUAL UNION SELECT ''f,g'',2 FROM DUAL UNION SELECT ''h'',3 FROM DUAL ) SELECT UNIQUE(slno),REGEXP_SUBSTR(temp,''[^,]+'', 1, LEVEL)temp FROM cte CONNECT BY LEVEL<=REGEXP_COUNT(temp, ''[^,]+'') ORDER BY slno;