none
¿Como puedo comparar dos tablas y sacar información de la segunda tabla y complementar la primera? RRS feed

  • 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

    lunes, 26 de febrero de 2018 19:43

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
    lunes, 26 de febrero de 2018 19:47
  • 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
    lunes, 26 de febrero de 2018 22:40
  • 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
    lunes, 26 de febrero de 2018 22:52
  • 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
    lunes, 26 de febrero de 2018 23:13
  • 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
    martes, 27 de febrero de 2018 18:40
  • 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
    martes, 27 de febrero de 2018 18:52
  • 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
    martes, 27 de febrero de 2018 19:12
  • 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
    martes, 27 de febrero de 2018 19:38
  • 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
    martes, 27 de febrero de 2018 22:06
  • 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
    martes, 27 de febrero de 2018 22:21

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
    lunes, 26 de febrero de 2018 19:47
  • 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
    lunes, 26 de febrero de 2018 22:40
  • 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
    lunes, 26 de febrero de 2018 22:52
  • 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
    lunes, 26 de febrero de 2018 23:13
  • 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
    martes, 27 de febrero de 2018 18:40
  • 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
    martes, 27 de febrero de 2018 18:52
  • 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
    martes, 27 de febrero de 2018 19:12
  • 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
    martes, 27 de febrero de 2018 19:38
  • 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

    • Marcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
    • Desmarcado como respuesta F3RC4O miércoles, 28 de febrero de 2018 21:28
    martes, 27 de febrero de 2018 19:39
  • 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
    martes, 27 de febrero de 2018 22:06
  • 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
    martes, 27 de febrero de 2018 22:21