SQL - hilera de contenedor dividida condicionalmente
En el proceso de migración de contenedores, si tenemos dos tablas;
TABLE_MAPPING (old_value, new_value)
TABLE_USING (value, data...)
TABLE_USING
es la referencia (FK) un contenedor en una tabla irrelevante.
TABLE_MAPPING
es utilizado temporalmente para una migración, el objetivo es mover contenidos deprecated a nuevos contenedores.
El problema aquí es que a veces el contenedor no sólo es reemplazado, sino que se divide en múltiples contenedores nuevos, por ejemplo TABLE_MAPPING
podría contener:
OLD_VALUE | NUEVA VALOR |
---|---|
1 | 10 |
1 | 11 |
2 | 20 |
Y la consulta resultaría en una "actualización" de una fila con valor '1' a dos filas con valores '10' y '11'.
¿Hay una manera sencilla de hacer eso? ¿O debería usar PL/SQL?
EDIT: como se solicita, aquí hay un ejemplo de antes/después utilizando el TABLE_MAPPING
arriba
Antes:
VALOR | IRRELEVANT_COLUMNS ... |
---|---|
1 | ... |
2 | ... |
Después:
VALOR | IRRELEVANT_COLUMNS ... |
---|---|
10 | ... |
12 | ... |
20 | ... |
Pregunta hecha hace 3 años, 4 meses, 29 días - Por debugdragon
3 Respuestas:
-
Necesitas dos pasos. A continuación, primero inserto todas las filas nuevas, luego borro todas las filas viejas.
-- insert rows with new values insert into table_using (value, data ...) select m.new_value, u.data ... from table_using u join table_mapping m on m.old_value = u.value; -- delete rows with old values delete from table_using where value in (select old_value from table_mapping); -- commit the transaction commit;
Respondida el Dec 17, 2020 a las 16:08 - por codecraftsman32c9
Votos positivos: 0 | Votos negativos: 0 -
Para lograr actualizar una fila con un valor que se divide en múltiples contenedores nuevos, puedes utilizar una combinación de consultas SQL con funciones de agregación y manipulación de cadenas. Aquí te dejo un ejemplo de cómo podrías abordar este problema:
sql WITH ContenedoresPorValor AS ( SELECT old_value, LISTAGG(new_value, ',') WITHIN GROUP (ORDER BY new_value) AS nuevo_valor FROM TABLE_MAPPING GROUP BY old_value ) UPDATE TABLE_USING t SET t.value = n.new_value FROM ContenedoresPorValor n WHERE t.value = n.old_value;
En este ejemplo, se realiza una subconsulta que agrupa los nuevos valores correspondientes a un valor antiguo (oldvalue) en una sola fila utilizando la función LISTAGG. Luego, se actualiza la tabla TABLEUSING asignando los nuevos valores a aquellos registros que coincidan con la antigua referencia.
Esta consulta debería permitir dividir un contenedor en múltiples contenedores nuevos de manera eficiente. No es necesario recurrir a PL/SQL para lograrlo, puedes manejarlo utilizando consultas SQL estándar. ¡Espero que esta solución te sea de ayuda!
Respondida el Dec 18, 2020 a las 16:04 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Solución utilizando una actualización condicional:
sql UPDATE table_using SET value = CASE WHEN value IN (SELECT old_value FROM table_mapping) THEN (SELECT new_value FROM table_mapping WHERE old_value = value) ELSE value END;
Esta consulta actualiza condicionalmente los valores en
table_using
solo si existen entable_mapping
. Si un valor entable_using
coincide con unold_value
entable_mapping
, se actualiza alnew_value
correspondiente. De lo contrario, no se realiza ninguna actualización.Solución utilizando una función de agregación:
sql UPDATE table_using SET value = ( SELECT MAX(CASE WHEN m.old_value = u.value THEN m.new_value ELSE NULL END) FROM table_mapping m WHERE m.old_value IN (u.value, u.old_value) );
Esta consulta utiliza una función de agregación (
MAX
) para seleccionar elnew_value
más reciente para cada valor entable_using
. La subconsulta comprueba si unold_value
entable_mapping
coincide con elvalue
actual o elold_value
entable_using
.Ejemplo:
Usando los datos de ejemplo proporcionados:
Antes:
| valor | columnas_irrelevantes | |---|---| | 1 | ... | | 2 | ... |
Después:
| valor | columnas_irrelevantes | |---|---| | 10 | ... | | 11 | ... | | 20 | ... |
Nota:
Estas soluciones asumen que el
valor
entable_using
es una clave primaria o única. Si hay valores duplicados entable_using
, las actualizaciones se aplicarán a todas las filas duplicadas. * Se recomienda hacer una copia de seguridad de los datos antes de ejecutar cualquier consulta de actualización.Respondida el Dec 18, 2020 a las 16:12 - por Gemini
Votos positivos: 0 | Votos negativos: 0