Principales respuestas
¿Como puedo comparar dos tablas y sacar información de la segunda tabla y complementar la primera?

Pregunta
-
Hola, estoy haciendo un proceso con C# y lo que tengo que hacer es consultar una tabla y rellenar la otra con los datos faltantes. Es decir, tengo que ver si en la tabla donde hace falta un dato y en la otra existe es como debo rellenarlo, y esto con un campo de identificación único. Me podrían apoyar con alguna idea de como hacerlo? Que es lo que dedo utilizar?
Fernando Cabañas
Respuestas
-
Hola Fernando:
Dado que el identificador es único y supongo que lo que tienes que comparar es la existencia del registro, porque no te traes solo los identificadores, a una lista de int, lo mismo de la segunda tabla, y luego comparas las dos listas, obtienendo las diferencias, a partir de ahi, te recoges los registros mediante la select oportuna cuyos identificadores, sean los elementos de la comparacíon y los insertas.
Otra opción es utilizar la sentencia merge, que se encarga de insertar si no existe y updatear si existe.
https://docs.microsoft.com/es-es/sql/t-sql/statements/merge-transact-sql
Un saludo
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
la forma mas facil de hacer eso es si validas si el dato existe en la otra table y si existe entonces ejecutas tu consulta
public static bool Existe(int id) { using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) { string query = "SELECT COUNT(*) FROM PERSONAS WHERE ID=@Id"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("Id", id); conn.Open(); int count = Convert.ToInt32(cmd.ExecuteScalar()); if (count == 0) return false; else return true; } }
aque validas si existe tu dato y si existe entonces haces tu consulta de ingreso de datos insert into, exito
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Yo diría que lo que ocupa es MERGE.
Merge Into tablaDestino As d Using tablaFuente As s On d.clave_primaria = s.clave_primaria --o algo similar When Not Matched By Target Insert Values (s.col1, s.col2, ...) ;
El MERGE es más potente que esto solamente, así que le encargo estudiar la instrucción y asegurarse de que le saca el máximo provecho.
Jose R. MCP
Code Samples- Propuesto como respuesta Willams Morales lunes, 26 de febrero de 2018 22:56
- Votado como útil Willams Morales martes, 27 de febrero de 2018 19:21
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Saludos
Si lo que vas a comparar son rows completas usuaria except si vas a comparar de una manera mas atomica digamos por un id, usaria merge como te han comentado.
Aunque por abajo la diferencia en performance seguramente sera igual, pero el except seria mas facil de codificar.
Blog: www.sqlservertoolbox.blogspot.com.mx
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Bueno, agradezco a todos la ayuda. Me he puesto ha investigar y he tratado algunos ejercicios sin dar el resultado esperado para mí. Y esto por lo siguiente; en la tabla de destino faltan algunos datos en algunas filas, cabe aclarar que lo que tengo que hacer es que de la tabla origen rellene solo los datos faltantes en la tabla destino las cuales están ligadas por un id, aún no logro hacer el update, alguna idea? Otra cosa es que debo preguntar, cuando pongo el update solamente puedo poner los campos a actualizar o debo poner toda la tabla?
Fernando Cabañas
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Saludos.
El merge los encontrara con el mismo id, entonces hazles un update o insert no sera la cosa mas optima y rápida pero debería de resolver el problema.
Blog: www.sqlservertoolbox.blogspot.com.mx
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Te sugiero invertir tiempo al escribir el post con una buena descripción del problema, el caso no debe ser nada complejo pero fíjate que ya tienes casi un día sin resolver el problema, cuanto más preciso seas en lo que requieres tendrás respuestas, dentro de lo posible, inmediatas y precisas.
Por lo que entiendo, la actualización debe ser bajo la siguiente forma:
UPDATE d SET d.Col1 = CASE WHEN d.Col1 IS NULL THEN o.Col1 ELSE d.Col1 END, d.Col2 = CASE WHEN d.Col2 IS NULL THEN o.Col2 ELSE d.Col1 END, d.Col3 = CASE WHEN d.Col3 IS NULL THEN o.Col3 ELSE d.Col1 END FROM dbo.TablaOrigen o INNER JOIN dbo.TablaDestino d ON o.id = d.id WHERE d.Col1 IS NULL OR d.Col2 IS NULL OR d.Col3 IS NULL; GO
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Como le mencioné en mi primera respuesta, el MERGE hace más que solamente lo que le mostré.
Merge Into tablaDestino As d Using tablaFuente As s On d.clave_primaria = s.clave_primaria --o algo similar When Matched Update Set d.Campo = s.Campo, d.Campo2 = s.Campo2, ... When Not Matched By Target Insert Values (s.col1, s.col2, ...) ;
Jose R. MCP
Code Samples- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Yo lo haría directamente en un procedimiento almacenado donde en una subconsulta y con un Left Join o Right Join según sea el caso extraigo los registros faltantes. Y este resultado se lo envío a la consulta de afuera creando el insert.
Traer todos los registros donde tabla1 Right Join Tabla2 on Tabla1.Campo1 Is null algo asi seria
- Editado Jhon Cifuentes martes, 27 de febrero de 2018 22:08
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Debo aclarar que los datos son todos diferentes, y el campo por el cual me tengo que guiar para verificar que los datos existen es la curp, que es como el id. Y lo que tengo que rellenar son los numeros_nomina que hay en la tabla origen a la tabla destino. Sé poco del tema espero lo entiendan.
Se resuelve de la manera que te indiqué en el ejemplo anterior, con independencia de la forma como ejecutes la actualización. Con los datos que nos has compartido quedaría de la siguiente forma:
UPDATE d SET d.numero_nomina = o.numero_nomina FROM dbo.TablaOrigen o INNER JOIN dbo.TablaDestino d ON o.curp = d.curp WHERE d.numero_nomina IS NULL AND o.numero_nomina IS NOT NULL; GO
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
Todas las respuestas
-
Hola Fernando:
Dado que el identificador es único y supongo que lo que tienes que comparar es la existencia del registro, porque no te traes solo los identificadores, a una lista de int, lo mismo de la segunda tabla, y luego comparas las dos listas, obtienendo las diferencias, a partir de ahi, te recoges los registros mediante la select oportuna cuyos identificadores, sean los elementos de la comparacíon y los insertas.
Otra opción es utilizar la sentencia merge, que se encarga de insertar si no existe y updatear si existe.
https://docs.microsoft.com/es-es/sql/t-sql/statements/merge-transact-sql
Un saludo
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
la forma mas facil de hacer eso es si validas si el dato existe en la otra table y si existe entonces ejecutas tu consulta
public static bool Existe(int id) { using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) { string query = "SELECT COUNT(*) FROM PERSONAS WHERE ID=@Id"; SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("Id", id); conn.Open(); int count = Convert.ToInt32(cmd.ExecuteScalar()); if (count == 0) return false; else return true; } }
aque validas si existe tu dato y si existe entonces haces tu consulta de ingreso de datos insert into, exito
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Yo diría que lo que ocupa es MERGE.
Merge Into tablaDestino As d Using tablaFuente As s On d.clave_primaria = s.clave_primaria --o algo similar When Not Matched By Target Insert Values (s.col1, s.col2, ...) ;
El MERGE es más potente que esto solamente, así que le encargo estudiar la instrucción y asegurarse de que le saca el máximo provecho.
Jose R. MCP
Code Samples- Propuesto como respuesta Willams Morales lunes, 26 de febrero de 2018 22:56
- Votado como útil Willams Morales martes, 27 de febrero de 2018 19:21
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Saludos
Si lo que vas a comparar son rows completas usuaria except si vas a comparar de una manera mas atomica digamos por un id, usaria merge como te han comentado.
Aunque por abajo la diferencia en performance seguramente sera igual, pero el except seria mas facil de codificar.
Blog: www.sqlservertoolbox.blogspot.com.mx
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Bueno, agradezco a todos la ayuda. Me he puesto ha investigar y he tratado algunos ejercicios sin dar el resultado esperado para mí. Y esto por lo siguiente; en la tabla de destino faltan algunos datos en algunas filas, cabe aclarar que lo que tengo que hacer es que de la tabla origen rellene solo los datos faltantes en la tabla destino las cuales están ligadas por un id, aún no logro hacer el update, alguna idea? Otra cosa es que debo preguntar, cuando pongo el update solamente puedo poner los campos a actualizar o debo poner toda la tabla?
Fernando Cabañas
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:27
-
Saludos.
El merge los encontrara con el mismo id, entonces hazles un update o insert no sera la cosa mas optima y rápida pero debería de resolver el problema.
Blog: www.sqlservertoolbox.blogspot.com.mx
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Te sugiero invertir tiempo al escribir el post con una buena descripción del problema, el caso no debe ser nada complejo pero fíjate que ya tienes casi un día sin resolver el problema, cuanto más preciso seas en lo que requieres tendrás respuestas, dentro de lo posible, inmediatas y precisas.
Por lo que entiendo, la actualización debe ser bajo la siguiente forma:
UPDATE d SET d.Col1 = CASE WHEN d.Col1 IS NULL THEN o.Col1 ELSE d.Col1 END, d.Col2 = CASE WHEN d.Col2 IS NULL THEN o.Col2 ELSE d.Col1 END, d.Col3 = CASE WHEN d.Col3 IS NULL THEN o.Col3 ELSE d.Col1 END FROM dbo.TablaOrigen o INNER JOIN dbo.TablaDestino d ON o.id = d.id WHERE d.Col1 IS NULL OR d.Col2 IS NULL OR d.Col3 IS NULL; GO
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Como le mencioné en mi primera respuesta, el MERGE hace más que solamente lo que le mostré.
Merge Into tablaDestino As d Using tablaFuente As s On d.clave_primaria = s.clave_primaria --o algo similar When Matched Update Set d.Campo = s.Campo, d.Campo2 = s.Campo2, ... When Not Matched By Target Insert Values (s.col1, s.col2, ...) ;
Jose R. MCP
Code Samples- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Bueno, tengo la siguiente tabla llamada origen con los siguientes campos:
| id | ur | ciclo | periodo | tipo_nomina | numero_nomina | num_comprobante_pago | primer_apellido | segundo_apellido | nombre | curp | rfc | nomina |
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
Y obviamente en la otra tabla llamada destino tengo los mismo campos, ahora lo que necesito hacer es rellenar el campo faltante que es numero_nomina. El detalle es el siguienteLa información la tengo así:
| id | ur | ciclo | periodo | tipo_nomina | numero_nomina | num_comprobante_pago | primer_apellido | segundo_apellido | nombre | curp | rfc | nomina |
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 698584 rodriguez perez juan prj650815H prj6508 60
1 2016 201601 P 5 123456789 698584 rodriguez perez juan prj650815H prj6508 60
Debo aclarar que los datos son todos diferentes, y el campo por el cual me tengo que guiar para verificar que los datos existen es la curp, que es como el id. Y lo que tengo que rellenar son los numeros_nomina que hay en la tabla origen a la tabla destino. Sé poco del tema espero lo entiendan.Pongo una imagen para que se pueda apreciar bien el formato del texto:
Fernando Cabañas
-
Yo lo haría directamente en un procedimiento almacenado donde en una subconsulta y con un Left Join o Right Join según sea el caso extraigo los registros faltantes. Y este resultado se lo envío a la consulta de afuera creando el insert.
Traer todos los registros donde tabla1 Right Join Tabla2 on Tabla1.Campo1 Is null algo asi seria
- Editado Jhon Cifuentes martes, 27 de febrero de 2018 22:08
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
-
Debo aclarar que los datos son todos diferentes, y el campo por el cual me tengo que guiar para verificar que los datos existen es la curp, que es como el id. Y lo que tengo que rellenar son los numeros_nomina que hay en la tabla origen a la tabla destino. Sé poco del tema espero lo entiendan.
Se resuelve de la manera que te indiqué en el ejemplo anterior, con independencia de la forma como ejecutes la actualización. Con los datos que nos has compartido quedaría de la siguiente forma:
UPDATE d SET d.numero_nomina = o.numero_nomina FROM dbo.TablaOrigen o INNER JOIN dbo.TablaDestino d ON o.curp = d.curp WHERE d.numero_nomina IS NULL AND o.numero_nomina IS NOT NULL; GO
- Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28