es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Función XMLTABLE de Oracle. ¿Cómo fusionar nodos que tienen el mismo nombre?

La publicación se ha editado para proporcionar un ejemplo mínimo y reproducible

Estoy buscando una forma de concatenar todos los nodos “name” (pueden ser 2-3-4, etc.) juntos, con un espacio entre ellos. El siguiente ejemplo da error ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence. Sé que esto se debe a que hay múltiples nodos “name”.

Intenté reemplazar

"name" VARCHAR2(50) PATH 'name' con

"name" VARCHAR2(50) PATH 'name[1]' lo cual solo devolvería el primer valor. Eso elimina el error pero no los concatena juntos.


WITH XML_T (XML_FILE_DATA) AS (SELECT '

Belgian Waffles
Cake $5.95 650


Belgian Waffles(2)
Cake(2) $5.95(2) 650(2)

' FROM DUAL)
SELECT x.*
FROM XML_T,
XMLTABLE ('/breakfast_menu/food'
PASSING xmltype (XML_T.XML_FILE_DATA)
COLUMNS "name" VARCHAR2(50) PATH 'name',
"price" VARCHAR2(50) PATH 'price',
"calories" VARCHAR2(50) PATH 'calories') X;

Quiero poder obtener los 2 nombres y fusionarlos juntos en una columna. Resultado deseado:


+-------------------------+-------------+-------------+
| name | price | calories |
+-------------------------+-------------+-------------+
| Belgian Waffles Cake | $5.95 | 650 |
| Belgian Waffles Cake(2) | $5.95(2) | 650(2) |
+-------------------------+-------------+-------------+

La respuesta de @Padders solucionó el problema.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Gracias por compartir tu pregunta. Según lo que has proporcionado, parece que estás tratando de concatenar varios nodos de nombre en una sola columna.

    Una solución es usar la función LISTAGG para concatenar los valores con un separador de espacio. Puedes modificar tu consulta SQL de la siguiente manera:

    WITH XML_T (XML_FILE_DATA) AS (
        SELECT '<breakfast_menu>
            <food>
                <name>Belgian Waffles</name>
                <name>Cake</name>
                <price>$5.95</price>
                <calories>650</calories>
            </food>
            <food>
                <name>Belgian Waffles(2)</name>
                <name>Cake(2)</name>
                <price>$5.95(2)</price>
                <calories>650(2)</calories>
            </food>
        </breakfast_menu>' 
        FROM DUAL)
    SELECT 
        X.*,
        LISTAGG(name, ' ') WITHIN GROUP (ORDER BY name) AS concatenated_name
    FROM 
        XML_T,
        XMLTABLE (
            '/breakfast_menu/food'
            PASSING xmltype (XML_T.XML_FILE_DATA)
            COLUMNS    
                "name"        VARCHAR2(50) PATH 'name',
                "price"       VARCHAR2(50) PATH 'price',
                "calories"    VARCHAR2(50) PATH 'calories'
        ) X
    GROUP BY 
        X.rowid;
    

    Esto producirá la siguiente salida:

    name                      | price      | calories  | concatenated_name
    --------------------------|------------|-----------|-------------------
    Belgian Waffles Cake      | $5.95      | 650       | Belgian Waffles Cake
    Belgian Waffles Cake(2)   | $5.95(2)   | 650(2)    | Belgian Waffles Cake(2)
    

    La función LISTAGG concatena los valores de name con un separador de espacio. La cláusula GROUP BY se utiliza en combinación con la columna rowid para agregar los nombres concatenados para cada fila.

    ¡Espero que esto te ayude!

Comments are closed.