La sentencia JOIN le permite trabajar con datos almacenados en múltiples tablas. Cruzar tablas es una tarea común en MySQL para combinar datos de múltiples tablas en una sola consulta. Al combinar datos de varias tablas, puedes obtener información valiosa y tomar decisiones informadas.
La cláusula JOIN nos permite combinar las columnas de dos o más tablas basándose en valores de columnas compartidas. Cuando las columnas que enlazan las tablas apuntan a la clave primaria de la tabla relacionada, entonces estamos hablando de claves foráneas. En este caso, es mejor incluir esta relación como parte de la definición de la tabla, ya que aumentará el rendimiento.
Tipos de Sentencias JOIN
Existen varios tipos de JOINs, cada uno diseñado para diferentes necesidades de combinación de datos:
- INNER JOIN: La operación INNER JOIN combina filas de dos o más tablas solo si hay una correspondencia entre las claves primarias y foráneas de las tablas. Esta operación se utiliza para obtener solo los registros que tienen correspondencias entre las tablas que se están uniendo.
- LEFT [OUTER] JOIN: La operación LEFT JOIN devuelve todas las filas de la tabla de la izquierda (tabla izquierda) y las filas correspondientes de la tabla de la derecha (tabla derecha). Si no hay correspondencia entre las dos tablas, se devolverán valores nulos.
- RIGHT [OUTER] JOIN: Por último, la operación RIGHT JOIN devuelve todas las filas de la tabla de la derecha (tabla derecha) y las filas correspondientes de la tabla de la izquierda (tabla izquierda). Si no hay correspondencia entre las dos tablas, se devolverán valores nulos.
- FULL [OUTER] JOIN: Se trata esencialmente de la combinación de un LEFT JOIN y un RIGHT JOIN. El conjunto de resultados incluirá todas las filas de ambas tablas, rellenando las columnas con los valores de la tabla cuando sea posible o con NULLs cuando no haya ninguna coincidencia en la tabla homóloga. Este no es un JOIN que vaya a utilizar muy a menudo en la vida real.
- CROSS JOIN: Este es otro tipo de unión que no usará muy a menudo. En este caso, recupera el producto cartesiano de ambas tablas. Básicamente, esto le da la combinación de todos los registros de ambas tablas. CROSS JOIN no aplica un predicado (no hay una palabra clave ON), pero todavía es posible filtrar filas usando WHERE.
Resumen de Tipos de JOIN
| Tipo de JOIN | Descripción |
|---|---|
| INNER JOIN | Devuelve registros que tienen una coincidencia en ambas tablas según el predicado de unión. |
| LEFT JOIN | Devuelve todas las filas de la tabla de la izquierda y las filas coincidentes de la tabla de la derecha. Si no hay coincidencia, devuelve NULLs. |
| RIGHT JOIN | Devuelve todas las filas de la tabla de la derecha y las filas coincidentes de la tabla de la izquierda. Si no hay coincidencia, devuelve NULLs. |
| FULL JOIN | Combina un LEFT JOIN y un RIGHT JOIN, incluyendo todas las filas de ambas tablas y NULLs donde no hay coincidencia. (Uso poco frecuente). |
| CROSS JOIN | Devuelve el producto cartesiano de ambas tablas (todas las combinaciones posibles). No usa ON. (Uso poco frecuente). |
Implementando JOINs en PHP
Veamos ahora cómo utilizar los "joins" de MySQL en PHP, y cómo se comportan y cómo podemos corregir algunos problemas de su comportamiento. Un escenario común en tiempo real trata con datos que siguen este tipo de relación. Por ejemplo, un user se encuentra en un city que pertenece a un state.
Imaginemos que necesitamos, en lugar de que nos muestre el identificador de estatus y el identificador de tipo, necesitamos mostrar el nombre. Con lo cual, tendríamos que hacer un 'join' entre la tabla de 'user' y 'status', y 'user' y 'user_type'.
Lea también: IVA 21% Excel
Vamos a hacerlo entonces para la tabla de 'status'. Para construir la consulta SQL, indicaríamos que seleccione todos los campos de la tabla de 'user', y de la tabla 'status' solo selecciona el campo 'name'. Luego, haríamos 'join' con 'INNER JOIN', con la tabla 'status' y, por último, le diríamos en qué campo va a hacer el pivote. Entonces, utilizaríamos una condición como: 'user.status_id = status.id'. Esto es una buena práctica poner de qué tabla estás obteniendo cada dato, por legibilidad y además porque aquí tenemos que indicarle que el campo ID es de la tabla 'status'.
Manejo de Alias de Columnas en PHP
Al trabajar con resultados de un JOIN en PHP, es fundamental comprender cómo se manejan los alias. Un error común es intentar acceder a los datos utilizando los alias de las tablas, como en echo="pv.nombre" con la función mysql_fetch_array.
No has entendido el uso de los alias puestos en las columnas. Si te fijas con cuidado, al lado de cada columna hay un alias adicional y ese es el nombre de la columna para el momento en que el PHP recupera los datos. Los alias de las tablas nunca aparecerán en PHP, sólo el nombre de la columna, o, en este caso, el alias que se le puso en el SELECT. Por ejemplo, si en tu consulta SQL usas SELECT pv.nombre AS nombre_promovido FROM ..., en PHP accederías a $fila['nombre_promovido'].
JOINs Dinámicos con Variables PHP
A menudo, se pretende cambiar los números por variables enviadas desde un FORM para hacer búsquedas, lo que implica construir consultas JOIN dinámicamente con PHP. Sin embargo, es crucial asegurar que la sintaxis del INNER JOIN esté bien redactada, ya que una construcción incorrecta puede llevar a resultados erróneos.
Buenas Prácticas para el Uso de JOINs
Una regla general es que los predicados de JOIN (las condiciones después de la palabra clave ON) deben usarse solo para la relación de unión. Deje el resto de las condiciones de filtrado dentro de la sección WHERE. Esto ayuda a mantener la consulta clara y eficiente. Además, la cláusula DISTINCT filtra los registros duplicados, lo cual es útil cuando un JOIN puede generar múltiples filas para una misma entidad, por ejemplo, si hay varios usuarios para un estado.
Lea también: Guía IVA reducido
Otro escenario típico para JOINs es cuando los registros se relacionan entre sí de una manera "muchos-a-muchos" o N-a-N. Por ejemplo, si tienes un sistema en el que creas insignias que se otorgan a los usuarios. En este caso, un usuario tiene insignias y, al mismo tiempo, una insignia tiene usuarios. Estas relaciones necesitarán una tercera tabla que conecte las claves primarias de users y badges. Aquí podemos utilizar un LEFT JOIN a propósito porque mostrará a los usuarios que no tienen ninguna insignia. Si hubiéramos utilizado un INNER JOIN o un inner join implícito (estableciendo las igualdades del ID en un WHERE), los usuarios que no tienen insignias no se incluirían en los resultados. Por último, recuerde indexar correctamente la tabla intermedia (badges_users) para optimizar el rendimiento.
Lea también: ¿Cómo localizar tus XML del SAT?
