5th Dec 2022 Lectura de 10 minutos ¿Cómo deshacerse de los duplicados en un JOIN SQL? Kateryna Koidan SQL aprender SQL sql joins Índice Tipos de JOIN en SQL Visión general ¿Cuáles son las razones de los duplicados en Tipos de JOIN en SQL? 1. Falta la condición ON 2. Uso de una condición ON incompleta 3. Seleccionar un subconjunto de columnas 4. Listado de filas coincidentes solamente 5. Uso de autouniones ¡Practiquemos Tipos de JOIN en SQL! ¿Tiene duplicados no deseados en su consulta SQL JOIN? En este artículo, hablaré de las posibles razones por las que se obtienen duplicados después de unir tablas en SQL y mostraré cómo arreglar una consulta dependiendo de la razón detrás de los duplicados. Los analistas de datos con poca experiencia en Tipos de JOIN en SQL a menudo encuentran duplicados no deseados en el conjunto de resultados. Para los principiantes es un reto identificar la razón detrás de estos duplicados en los JOINs. La mejor manera de aprender Tipos de JOIN en SQL es mediante la práctica. Recomiendo el curso interactivo Tipos de JOIN en SQL curso interactivo. Contiene más de 90 ejercicios que te hacen practicar los diferentes tipos de JOIN en SQL. En este artículo, discutiré los problemas más comunes que conducen a los duplicados en los resultados de los JOINs de SQL. También mostraré las posibles soluciones a estos problemas comunes. Comencemos con una breve descripción de Tipos de JOIN en SQL. Tipos de JOIN en SQL Visión general JOIN es una construcción SQL para solicitar información de dos o más tablas dentro de la misma consulta. Por ejemplo, digamos que tienes una lista de las 100 mejores películas del siglo XX, y quieres hacer un subconjunto de las películas hechas por directores que viven actualmente. En su movies no tiene información detallada sobre los directores de cine, sino sólo sus identificaciones. Pero tiene una tabla separada directors con el ID, el nombre completo, el año de nacimiento y el año de fallecimiento (si procede) de cada director. En su consulta, puede unir dos tablas por el ID del director para obtener una lista de las películas realizadas por los directores que viven actualmente: SELECT movies.title, directors.full_name FROM movies JOIN directors ON movies.director_id = directors.id WHERE directors.death_year IS NULL; Como puedes ver, especificamos las tablas que queremos unir en las cláusulas FROM y JOIN. Luego, en la cláusula ON, especificamos las columnas de cada tabla que se utilizarán para unir estas tablas. Si usted es nuevo en Tipos de JOIN en SQL, revise esta guía introductoria. Aquí también hay una hoja de trucos de SQL JOIN con sintaxis y ejemplos de diferentes JOINs. El SQL JOIN es una gran herramienta que proporciona una variedad de opciones más allá de la simple unión de dos tablas. Si no está familiarizado con los tipos de JOIN de SQL, lea este artículo que los explica con ilustraciones y ejemplos. Dependiendo de su caso de uso, puede elegir INNER JOIN, LEFT JOIN, RIGHT JOIN y FULL JOIN. Incluso puede necesitar unir tablas sin una columna común o unir más de dos tablas. Ahora, veamos como estos diferentes JOINs pueden resultar en duplicados no deseados. ¿Cuáles son las razones de los duplicados en Tipos de JOIN en SQL? Hay muchas razones posibles para obtener duplicados en el resultado de su consulta SQL JOIN. Revisaré las 5 razones principales; para cada una, mostraré una consulta de ejemplo con el problema y una consulta corregida para obtener un resultado sin duplicados. Empecemos por repasar brevemente los datos que vamos a utilizar en nuestros ejemplos. Imaginemos que tenemos una agencia inmobiliaria que vende casas en algún lugar de Estados Unidos. Tenemos tablas con agents, customers, y sales. Vea a continuación qué datos se almacenan en cada tabla. agents idfirst_namelast_nameexperience_years 1KateWhite5 2MelissaBrown2 3AlexandrMcGregor3 4SophiaScott3 5StevenBlack1 6MariaScott1 customers idfirst_namelast_nameemail 11XavieraLopezxaviera111111@gmail.com 12GabrielCumberlygabriel111111@gmail.com 13ElisabethStevenselisabeth111111@gmail.com 14OprahWinfreyoprah111111@gmail.com 15IvanLeeivan111111@gmail.com sales idhouse_iddateagent_first_nameagent_last_namecustomer_idprice 10110122021-11-03KateWhite141200000 10221342021-12-06SophiaScott12950000 10310152021-12-10MariaScott13800000 10420132021-12-12AlexandrMcGregor151350000 10521122021-12-12AlexandrMcGregor151450000 10610102022-01-10StevenBlack111500000 Sin más dilación, pasemos a nuestros ejemplos. 1. Falta la condición ON Los principiantes que no están familiarizados con Tipos de JOIN en SQL suelen limitarse a enumerar las tablas en FROM sin especificar en absoluto la condición JOIN cuando intentan combinar información de dos o más tablas. Esta es una sintaxis válida, por lo que no se obtiene ningún mensaje de error. Pero el resultado es una unión cruzada con todas las filas de una tabla combinadas con todas las filas de otra tabla. Por ejemplo, supongamos que queremos obtener información sobre el cliente que compró una casa en particular (ID #2134). Si utilizamos la siguiente consulta: SELECT house_id, first_name, last_name, email FROM sales, customers WHERE house_id = 2134; Este es el resultado que obtenemos: house_idfirst_namelast_nameemail 2134XavieraLopezxaviera111111@gmail.com 2134GabrielCumberlygabriel111111@gmail.com 2134ElisabethStevenselisabeth111111@gmail.com 2134OprahWinfreyoprah111111@gmail.com 2134IvanLeeivan111111@gmail.com En lugar de un registro con el cliente que queremos, tenemos todos los clientes listados en el conjunto de resultados. Para arreglar la consulta, se necesita una sintaxis explícita de JOIN. Las tablas a combinar se especifican en FROM y JOIN, y la condición de unión se especifica en la cláusula ON: SELECT s.house_id, c.first_name, c.last_name, c.email FROM sales s JOIN customers c ON s.customer_id = c.id WHERE s.house_id = 2134; Aquí, especificamos el ID de cliente de la tabla sales para que coincida con el ID de cliente de la tabla customers de la tabla. Esto nos da el resultado deseado: house_idfirst_namelast_nameemail 2134GabrielCumberlygabriel111111@gmail.com Se podría especificar la condición de unión en la cláusula WHERE para obtener el mismo resultado. Pero eso va en contra del uso previsto de la cláusula WHERE. Además, existen beneficios adicionales al utilizar la sintaxis JOIN en lugar de listar las tablas en FROM. Consulte este artículo para entender por qué se prefiere la sintaxis de JOIN. 2. Uso de una condición ON incompleta Las filas no deseadas en el conjunto de resultados pueden provenir de condiciones ON incompletas. En algunos casos, es necesario unir tablas por varias columnas. En estas situaciones, si se utiliza sólo un par de columnas, se obtienen filas duplicadas. Digamos que queremos ver el nivel de experiencia del agente inmobiliario para cada casa vendida. Si empezamos uniendo las tablas sales y agents por el apellido del agente: SELECT s.house_id, a.first_name, a.last_name, a.experience_years FROM sales s JOIN agents a ON s.agent_last_name = a.last_name ORDER BY s.house_id; Esto es lo que se obtiene: house_idfirst_namelast_nameexperience_years 1010StevenBlack1 1012KateWhite5 1015MariaScott1 1015SophiaScott3 2013AlexandrMcGregor3 2112AlexandrMcGregor3 2134MariaScott1 2134SophiaScott3 Eso no funcionó bien. Tenemos dos agentes diferentes con el apellido Scott: María y Sofía. Como resultado, las casas #1015 y #2134 están incluidas dos veces con diferentes agentes. Para solucionar esta consulta, tenemos que unir las tablas sales y agents utilizando dos pares de columnas, correspondientes al apellido y al nombre del agente: SELECT s.house_id, a.first_name, a.last_name, a.experience_years FROM sales s JOIN agents a ON s.agent_last_name = a.last_name AND s.agent_first_name = a.first_name ORDER BY s.house_id; Y aquí está el resultado que buscábamos. house_idfirst_namelast_nameexperience_years 1010StevenBlack1 1012KateWhite5 1015MariaScott1 2013AlexandrMcGregor3 2112AlexandrMcGregor3 2134SophiaScott3 Aunque el JOIN es una de las herramientas básicas de SQL, es necesario conocer los diferentes matices para unir tablas de forma efectiva. Recomiendo practicar Tipos de JOIN en SQL con este curso interactivo que cubre una variedad de escenarios de unión con 93 desafíos de codificación. 3. Seleccionar un subconjunto de columnas En algunos casos, los registros del conjunto de resultados no son duplicados pero parecen serlo porque el subconjunto de columnas seleccionado no muestra todas las diferencias entre los registros. Por ejemplo, imaginemos que queremos ver las fechas en que cada agente inmobiliario vendió una casa. Si utilizamos la siguiente consulta SELECT a.first_name, a.last_name, s.date FROM agents a JOIN sales s ON s.agent_last_name = a.last_name AND s.agent_first_name = a.first_name; se obtiene el siguiente resultado: first_namelast_namedate KateWhite2021-11-03 SophiaScott2021-12-06 AlexandrMcGregor2021-12-12 AlexandrMcGregor2021-12-12 MariaScott2021-12-10 StevenBlack2022-01-10 El conjunto de resultados incluye dos registros con Alexandr McGregor que parecen idénticos. Sin embargo, si se añade el ID de la casa a la consulta SELECT, se ve que estos dos registros corresponden a la venta de dos casas diferentes en el mismo día. Si no le interesa esta información adicional y quiere que sólo se muestre una fila, utilice DISTINCT: SELECT DISTINCT a.first_name, a.last_name, s.date FROM agents a JOIN sales s ON s.agent_last_name = a.last_name AND s.agent_first_name = a.first_name; Ahora, el resultado es: first_namelast_namedate KateWhite2021-11-03 SophiaScott2021-12-06 AlexandrMcGregor2021-12-12 MariaScott2021-12-10 StevenBlack2022-01-10 4. Listado de filas coincidentes solamente Un problema similar puede ocurrir si quiere listar sólo las filas de una tabla pero hay varios registros coincidentes en la otra tabla. En este caso, el conjunto de resultados se verá afectado por duplicados no deseados. Por ejemplo, digamos que queremos listar todos los clientes que compraron casas a través de nuestra agencia. Si utilizamos la siguiente consulta SELECT c.first_name, c.last_name, c.email FROM customers c JOIN sales s ON c.id = s.customer_id; este es el resultado: first_namelast_nameemail GabrielCumberlygabriel111111@gmail.com ElisabethStevenselisabeth111111@gmail.com XavieraLopezxaviera111111@gmail.com OprahWinfreyoprah111111@gmail.com IvanLeeivan111111@gmail.com IvanLeeivan111111@gmail.com Como ves, la tabla resultante incluye a Ivan Lee dos veces. Esto se debe a que compró dos casas y hay dos registros correspondientes en la tabla sales tabla. Una posible solución es utilizar DISTINCT como en el ejemplo anterior. Una solución aún mejor es evitar el uso de SQL JOIN en absoluto, filtrando el conjunto de resultados mediante la palabra clave EXISTS: SELECT c.first_name, c.last_name, c.email FROM customers c WHERE EXISTS (SELECT customer_id FROM sales); Ahora, el resultado es: first_namelast_nameemail GabrielCumberlygabriel111111@gmail.com ElisabethStevenselisabeth111111@gmail.com XavieraLopezxaviera111111@gmail.com OprahWinfreyoprah111111@gmail.com IvanLeeivan111111@gmail.com Esto le da la salida deseada y también hace que la intención de su consulta sea más clara. 5. Uso de autouniones Por último, los duplicados no deseados en los JOINs suelen ser el resultado de una especificación incorrecta de las condiciones de unión en los self joins - es decir, cuando una tabla se une consigo misma. Digamos que queremos que nuestros agentes formen parejas para nuestro próximo entrenamiento. Obviamente, no queremos que ningún agente se empareje consigo mismo. Así que podríamos especificar la condición ON a1.id <> a2.id : SELECT a1.first_name as agent1_first_name, a1.last_name as agent1_last_name, a1.experience_years as agent1_experience, a2.first_name as agent2_first_name, a2.last_name as agent2_last_name, a2.experience_years as agent2_experience FROM agents a1 JOIN agents a2 ON a1.id <> a2.id ORDER BY a1.id; Sin embargo, esta consulta muestra cada pareja dos veces. Por ejemplo, en la primera fila de la tabla que aparece a continuación, Kate White se considera el agente 1 y Maria Scott el agente 2. Pero más cerca del final de la tabla, se obtiene el mismo par de agentes pero con María Scott como Agente 1 y Kate White como Agente 2. agent1_first_nameagent1_last_nameagent1_experienceagent2_first_nameagent2_last_nameagent2_experience KateWhite5MariaScott1 KateWhite5StevenBlack1 KateWhite5MelissaBrown2 KateWhite5SophiaScott3 KateWhite5AlexandrMcGregor3 MelissaBrown2StevenBlack1 MelissaBrown2SophiaScott3 MelissaBrown2MariaScott1 MelissaBrown2AlexandrMcGregor3 MelissaBrown2KateWhite5 AlexandrMcGregor3MariaScott1 AlexandrMcGregor3MelissaBrown2 AlexandrMcGregor3SophiaScott3 AlexandrMcGregor3KateWhite5 AlexandrMcGregor3StevenBlack1 SophiaScott3MariaScott1 SophiaScott3StevenBlack1 SophiaScott3AlexandrMcGregor3 SophiaScott3MelissaBrown2 SophiaScott3KateWhite5 StevenBlack1SophiaScott3 StevenBlack1AlexandrMcGregor3 StevenBlack1MariaScott1 StevenBlack1MelissaBrown2 StevenBlack1KateWhite5 MariaScott1KateWhite5 MariaScott1AlexandrMcGregor3 MariaScott1SophiaScott3 MariaScott1StevenBlack1 MariaScott1MelissaBrown2 Para resolver este problema, es necesario añadir una condición explícita para incluir cada par sólo una vez. Una solución común es especificar la condición de unión a1.id < a2.id. Con esto, se obtiene el par Kate White y Maria Scott, pero no a la inversa. Esto se debe a que el ID de Kate (1) es un número menor que el ID de María (6). En la práctica, puede tener otras condiciones para emparejar a los agentes. Por ejemplo, puede querer emparejar a los agentes más experimentados (3+ años) con los menos experimentados (< 3 años). La condición de filtrado correspondiente en WHERE resuelve el problema: SELECT a1.first_name as agent1_first_name, a1.last_name as agent1_last_name, a1.experience_years as agent1_experience, a2.first_name as agent2_first_name, a2.last_name as agent2_last_name, a2.experience_years as agent2_experience FROM agents a1 JOIN agents a2 ON a1.id <> a2.id WHERE a1.experience_years>=3 AND a2.experience_years < 3 ORDER BY a1.id; Este es el resultado: agent1_first_nameagent1_last_nameagent1_experienceagent2_first_nameagent2_last_nameagent2_experience KateWhite5StevenBlack1 KateWhite5MelissaBrown2 KateWhite5MariaScott1 AlexandrMcGregor3MariaScott1 AlexandrMcGregor3StevenBlack1 AlexandrMcGregor3MelissaBrown2 SophiaScott3MariaScott1 SophiaScott3StevenBlack1 SophiaScott3MelissaBrown2 Este conjunto de resultados se ve mucho mejor y facilita la selección de tres parejas, cada una de ellas formada por un agente con más experiencia y otro con menos experiencia. ¡Practiquemos Tipos de JOIN en SQL! Unir tablas en SQL no es tan difícil. Pero requiere mucha práctica. Si quiere evitar trampas como duplicados no deseados en JOINs y registros perdidos, siga esta guía para practicar Tipos de JOIN en SQL. Si sólo tiene una experiencia básica con SQL y quiere combinar datos de varias tablas con más seguridad, le recomiendo este Tipos de JOIN en SQL curso interactivo. Cubre todos los tipos principales de JOINs así como la unión de una tabla consigo misma, la unión de múltiples tablas en una consulta y la unión de tablas en columnas no clave. Obtenga más detalles sobre este curso en este artículo de resumen. Bonificación. Aquí están las 10 mejores preguntas de entrevista de SQL JOIN con respuestas. Gracias por leer y ¡feliz aprendizaje! Tags: SQL aprender SQL sql joins