{"id":11230,"date":"2024-02-18T11:32:33","date_gmt":"2024-02-18T10:32:33","guid":{"rendered":"https:\/\/www.palentino.es\/blog\/?p=11230"},"modified":"2024-02-18T11:32:44","modified_gmt":"2024-02-18T10:32:44","slug":"relaciones-disponibles-entre-tablas-sql-en-los-principales-gestores-de-bases-de-datos-sql-join","status":"publish","type":"post","link":"https:\/\/www.palentino.es\/blog\/relaciones-disponibles-entre-tablas-sql-en-los-principales-gestores-de-bases-de-datos-sql-join\/","title":{"rendered":"Relaciones disponibles entre tablas SQL en los principales gestores de Bases de datos. #sql  #join"},"content":{"rendered":"<p>Las relaciones entre tablas en una base de datos SQL son fundamentales para organizar y acceder a los datos de manera eficiente. Estas relaciones se establecen mediante el uso de <strong>claves primarias<\/strong> (Primary Keys, PK) y<strong> claves for\u00e1neas<\/strong> (Foreign Keys, FK), permitiendo modelar las interacciones entre los diferentes conjuntos de datos.<\/p>\n<p>Existen tres tipos principales de relaciones: Uno a Uno (1:1), Uno a Muchos (1:N) y Muchos a Muchos (M:N).<\/p>\n<p>Veamos cada una en detalle:<a href=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/Relaciones.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11238\" src=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/Relaciones.png\" alt=\"\" width=\"754\" height=\"370\" srcset=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/Relaciones.png 754w, https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/Relaciones-300x147.png 300w\" sizes=\"auto, (max-width: 754px) 100vw, 754px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Las relaciones entre tablas en una base de datos SQL son fundamentales para organizar y acceder a los datos de manera eficiente. Estas relaciones se establecen mediante el uso de claves primarias (Primary Keys, PK) y claves for\u00e1neas (Foreign Keys, FK), permitiendo modelar las interacciones entre los diferentes conjuntos de datos. Existen tres tipos principales de relaciones: Uno a Uno (1:1), Uno a Muchos (1:N) y Muchos a Muchos (M:N). Veamos cada una en detalle:<\/p>\n<p><!--more--><\/p>\n<h3>1. Relaci\u00f3n Uno a Uno (1:1)<\/h3>\n<p>En una relaci\u00f3n 1:1, cada fila en una tabla est\u00e1 relacionada con no m\u00e1s de una fila en otra tabla. Este tipo de relaci\u00f3n se utiliza cuando se quiere separar la informaci\u00f3n por razones de dise\u00f1o o seguridad, pero cada elemento de una tabla solo puede estar asociado con un \u00fanico elemento de la otra tabla.<\/p>\n<p><strong>Ejemplo<\/strong>: Considera una tabla Usuarios donde cada usuario tiene una \u00fanica direcci\u00f3n. Se podr\u00eda tener una tabla Direcciones donde cada direcci\u00f3n est\u00e1 asociada con un solo usuario. La clave primaria de Usuarios se utiliza como clave for\u00e1nea en Direcciones.<\/p>\n<pre>CREATE TABLE Usuarios (\r\nUsuarioID INT PRIMARY KEY,\r\nNombre VARCHAR(100)\r\n);\r\n\r\nCREATE TABLE Direcciones (\r\nDireccionID INT PRIMARY KEY,\r\nUsuarioID INT UNIQUE,\r\nDireccion VARCHAR(255),\r\nCONSTRAINT FK_UsuarioDireccion FOREIGN KEY (UsuarioID)\r\nREFERENCES Usuarios(UsuarioID)\r\n);\r\n<\/pre>\n<p>La restricci\u00f3n<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">UNIQUE<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">UsuarioID<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>de la tabla<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Direcciones<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>asegura la relaci\u00f3n 1:1.<\/p>\n<h3>2. Relaci\u00f3n Uno a Muchos (1:N)<\/h3>\n<p>La relaci\u00f3n 1:N es la m\u00e1s com\u00fan en las bases de datos relacionales. En este caso, una fila en la tabla principal puede estar relacionada con una o muchas filas en la tabla relacionada, pero una fila en la tabla relacionada solo puede estar asociada con una fila en la tabla principal.<\/p>\n<p><strong>Ejemplo<\/strong>: Una tabla<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Profesores<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>y una tabla<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Cursos<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>. Un profesor puede ense\u00f1ar varios cursos, pero cada curso es ense\u00f1ado por un solo profesor.<\/p>\n<pre>CREATE TABLE Profesores (\r\nProfesorID INT PRIMARY KEY,\r\nNombre VARCHAR(100)\r\n);\r\n\r\nCREATE TABLE Cursos (\r\nCursoID INT PRIMARY KEY,\r\nProfesorID INT,\r\nNombreCurso VARCHAR(100),\r\nCONSTRAINT FK_CursoProfesor FOREIGN KEY (ProfesorID)\r\nREFERENCES Profesores(ProfesorID)\r\n);\r\n&lt;\/\r\n<\/pre>\n<p>En este caso,<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">ProfesorID<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Cursos<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>es una clave for\u00e1nea que referencia<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">ProfesorID<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Profesores<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>.<\/p>\n<h3>3. Relaci\u00f3n Muchos a Muchos (M:N)<\/h3>\n<p>Una relaci\u00f3n M:N permite que varias filas en una tabla est\u00e9n asociadas con varias filas en otra tabla. Esta relaci\u00f3n se implementa mediante una tabla intermedia (tambi\u00e9n llamada tabla de uni\u00f3n o tabla de asociaci\u00f3n) que contiene claves for\u00e1neas que apuntan a las claves primarias de las tablas relacionadas. <strong>Ejemplo<\/strong>: Una tabla<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Estudiantes<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>y una tabla<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">Cursos<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>. Un estudiante puede inscribirse en muchos cursos, y un curso puede ser elegido por muchos estudiantes.<\/p>\n<pre>CREATE TABLE Estudiantes (\r\nEstudianteID INT PRIMARY KEY,\r\nNombre VARCHAR(100)\r\n);\r\n\r\nCREATE TABLE Cursos (\r\nCursoID INT PRIMARY KEY,\r\nNombreCurso VARCHAR(100)\r\n);\r\n\r\nCREATE TABLE Inscripciones (\r\nEstudianteID INT,\r\nCursoID INT,\r\nFechaInscripcion DATE,\r\nPRIMARY KEY (EstudianteID, CursoID),\r\nCONSTRAINT FK_InscripcionEstudiante FOREIGN KEY (EstudianteID)\r\nREFERENCES Estudiantes(EstudianteID),\r\nCONSTRAINT FK_InscripcionCurso FOREIGN KEY (CursoID)\r\nREFERENCES Cursos(CursoID)\r\n);\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>En `Inscripciones`, las columnas `EstudianteID` y `CursoID` sirven como claves for\u00e1neas que juntas forman una clave primaria compuesta, estableciendo as\u00ed la relaci\u00f3n M:N entre `Estudiantes` y `Cursos`.<\/p>\n<p>Estos tipos de relaciones entre tablas son fundamentales para el dise\u00f1o y la normalizaci\u00f3n de bases de datos, permitiendo modelar relaciones complejas entre los datos de manera eficiente y flexible.<\/p>\n<p>&nbsp;<\/p>\n<p>En SQL, los JOINs son utilizados para combinar filas de dos o m\u00e1s tablas, bas\u00e1ndose en una columna relacionada entre ellas. Los tipos principales de JOINs son: INNER JOIN, LEFT JOIN (LEFT OUTER JOIN), RIGHT JOIN (RIGHT OUTER JOIN) y FULL OUTER JOIN. Cada uno de estos tipos de JOIN sirve para un prop\u00f3sito espec\u00edfico en la consulta de datos relacionales. Aqu\u00ed te explico c\u00f3mo funcionan:<\/p>\n<h3>1. INNER JOIN<\/h3>\n<p>El<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">INNER JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>selecciona registros que tienen valores coincidentes en ambas tablas. Es decir, devuelve solo las filas que tienen al menos una coincidencia en la otra tabla. Si no hay coincidencia, las filas no se incluyen en el resultado.<\/p>\n<pre>SELECT empleados.nombre, departamentos.nombre_departamento\r\nFROM empleados\r\nINNER JOIN departamentos ON empleados.departamento_id = departamentos.id;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Este ejemplo muestra los nombres de los empleados junto con los nombres de sus departamentos, pero solo incluye a aquellos empleados que est\u00e1n asignados a un departamento.<\/p>\n<h3>2. LEFT JOIN (o LEFT OUTER JOIN)<\/h3>\n<p>El<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">LEFT JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>devuelve todas las filas de la tabla izquierda (la primera tabla), y las filas coincidentes de la tabla derecha (la segunda tabla). Las filas que no tienen coincidencia en la tabla derecha tendr\u00e1n<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">NULL<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en las columnas de la tabla derecha.<\/p>\n<p><strong>Ejemplo:<\/strong><\/p>\n<pre>SELECT empleados.nombre, departamentos.nombre_departamento\r\nFROM empleados\r\nLEFT JOIN departamentos ON empleados.departamento_id = departamentos.id;\r\n<\/pre>\n<p>Aqu\u00ed, se obtienen todos los empleados, incluidos aquellos que no est\u00e1n asignados a ning\u00fan departamento. Para estos \u00faltimos, el<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">nombre_departamento<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>ser\u00e1<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">NULL<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>.<\/p>\n<h3>3. RIGHT JOIN (o RIGHT OUTER JOIN)<\/h3>\n<p>El<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">RIGHT JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>funciona de manera opuesta al<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">LEFT JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>: devuelve todas las filas de la tabla derecha, y las filas coincidentes de la tabla izquierda. Si no hay coincidencia en la tabla izquierda, el resultado tendr\u00e1<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">NULL<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en las columnas de la tabla izquierda.<\/p>\n<p><strong>Ejemplo:<\/strong><\/p>\n<pre>SELECT empleados.nombre, departamentos.nombre_departamento\r\nFROM empleados\r\nRIGHT JOIN departamentos ON empleados.departamento_id = departamentos.id;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>4. FULL OUTER JOIN<\/h3>\n<p>El<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">FULL OUTER JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>combina los resultados de<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">LEFT JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>y<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">RIGHT JOIN<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>. Devuelve todas las filas cuando hay una coincidencia en una de las tablas. Por lo tanto, muestra todas las filas de ambas tablas, con<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">NULL<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>en las columnas de una tabla cuando no hay coincidencias en la otra tabla.<\/p>\n<p><strong>Ejemplo:<\/strong><\/p>\n<pre>SELECT empleados.nombre, departamentos.nombre_departamento\r\nFROM empleados\r\nFULL OUTER JOIN departamentos ON empleados.departamento_id = departamentos.id;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h1>Variaciones en JOINS<\/h1>\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-38\">\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"relative flex w-full flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"flex flex-grow flex-col max-w-full\">\n<div class=\"min-h-[20px] text-message flex flex-col items-start gap-3 whitespace-pre-wrap break-words [.text-message+&amp;]:mt-5 overflow-x-auto\" data-message-author-role=\"assistant\" data-message-id=\"10fd846b-6231-44ee-ba6a-9f956b7c9d84\">\n<div class=\"markdown prose w-full break-words dark:prose-invert dark\">\n<p>A los tipos de JOINs en SQL habituales, se les pueden a\u00f1adir otros y se pueden resumir en las siguientes categor\u00edas, cada una con su prop\u00f3sito espec\u00edfico para combinar filas de dos o m\u00e1s tablas:<\/p>\n<ol>\n<li><strong>INNER JOIN<\/strong>: Devuelve filas cuando hay al menos una coincidencia en ambas tablas. Si no hay coincidencia, las filas no se muestran.<\/li>\n<li><strong>LEFT JOIN (o LEFT OUTER JOIN)<\/strong>: Devuelve todas las filas de la tabla izquierda, y las filas coincidentes de la tabla derecha. Las filas de la tabla izquierda que no tienen coincidencias en la tabla derecha se muestran con valores NULL en las columnas de la tabla derecha.<\/li>\n<li><strong>RIGHT JOIN (o RIGHT OUTER JOIN)<\/strong>: Devuelve todas las filas de la tabla derecha, y las filas coincidentes de la tabla izquierda. Las filas de la tabla derecha que no tienen coincidencias en la tabla izquierda se muestran con valores NULL en las columnas de la tabla izquierda.<\/li>\n<li><strong>FULL OUTER JOIN<\/strong>: Combina los resultados de LEFT JOIN y RIGHT JOIN. Devuelve todas las filas cuando hay una coincidencia en una de las tablas. Las filas que no tienen coincidencias en la otra tabla se muestran con valores NULL en las columnas de la tabla que falta.<\/li>\n<li><strong>CROSS JOIN<\/strong>: Produce el producto cartesiano de las dos tablas involucradas, combinando cada fila de la primera tabla con todas las filas de la segunda tabla.<\/li>\n<li><strong>SELF JOIN<\/strong>: No es un tipo de JOIN espec\u00edfico, sino una t\u00e9cnica que implica unir una tabla consigo misma, trat\u00e1ndola como si fueran dos tablas separadas.<\/li>\n<li><strong>NATURAL JOIN<\/strong>: Realiza un INNER JOIN autom\u00e1ticamente basado en columnas con el mismo nombre y tipo en ambas tablas. No es recomendable debido a su dependencia de la coincidencia de nombres de columna, lo que puede llevar a resultados inesperados.<\/li>\n<\/ol>\n<p>Adem\u00e1s de estos tipos principales, hay variaciones y t\u00e9cnicas espec\u00edficas como el uso de las cl\u00e1usulas<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">USING()<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>y<\/p>\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">ON<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>para especificar las condiciones de uni\u00f3n, que pueden simplificar o ajustar la sintaxis y el comportamiento de los JOINs.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-40\">\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"relative flex w-full flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"flex flex-grow flex-col max-w-full\">\n<div class=\"min-h-[20px] text-message flex flex-col items-start gap-3 whitespace-pre-wrap break-words [.text-message+&amp;]:mt-5 overflow-x-auto\" data-message-author-role=\"assistant\" data-message-id=\"ca18c5d3-c6e9-466e-8352-0fdd3c9b823a\">\n<div class=\"markdown prose w-full break-words dark:prose-invert dark\">\n<p>Aunque los principales (INNER, LEFT, RIGHT, FULL OUTER, CROSS, y NATURAL JOIN) cubren la mayor\u00eda de las necesidades, aqu\u00ed te presento algunas extensiones y conceptos relacionados que, dependiendo del sistema de gesti\u00f3n de bases de datos (DBMS), pueden ofrecer funcionalidades adicionales o simplificar ciertas operaciones:<\/p>\n<h3>1. JOINs Condicionales<\/h3>\n<p>No es un tipo de JOIN en s\u00ed, pero puedes escribir consultas que implementen l\u00f3gica condicional dentro de la cl\u00e1usula ON o WHERE para realizar JOINs basados en condiciones m\u00e1s complejas que simples equivalencias.<\/p>\n<h3>2. JOINs Exclusivos<\/h3>\n<p>Otra t\u00e9cnica, no un tipo espec\u00edfico de JOIN, que permite seleccionar filas que solo existen en una de las tablas y no en la otra. Esto se puede lograr usando LEFT JOIN o RIGHT JOIN combinado con una cl\u00e1usula WHERE que filtra las filas con NULL en la tabla unida.<\/p>\n<h3>3. OUTER APPLY y CROSS APPLY<\/h3>\n<p>Espec\u00edficos de SQL Server, estos operadores se parecen a los JOINs pero permiten unir una tabla a una funci\u00f3n de tabla valorada que toma columnas de la fila como argumentos en cada fila de la tabla izquierda (en el caso de OUTER APPLY) o realiza un producto cartesiano similar a CROSS JOIN con CROSS APPLY.<\/p>\n<h3>4. LATERAL JOIN (o simplemente LATERAL)<\/h3>\n<p>Disponible en PostgreSQL y otros sistemas de bases de datos, LATERAL permite que una subconsulta en la cl\u00e1usula FROM haga referencia a columnas de tablas que aparecen antes de ella en la cl\u00e1usula FROM. Esto es \u00fatil para realizar operaciones que dependen de cada fila de la tabla precedente, similar en esp\u00edritu a CROSS APPLY y OUTER APPLY en SQL Server.<\/p>\n<h3>5. HASH JOIN, MERGE JOIN, y NESTED LOOP JOIN<\/h3>\n<p>Estos son m\u00e1s sobre c\u00f3mo el DBMS ejecuta los JOINs bajo el cap\u00f3 en lugar de ser tipos de JOIN que un desarrollador especificar\u00eda en una consulta. Sin embargo, algunos DBMS permiten sugerencias (hints) que pueden influir en la elecci\u00f3n del algoritmo de JOIN:<\/p>\n<ul>\n<li><strong>HASH JOIN<\/strong>: Ideal para unir grandes conjuntos de datos.<\/li>\n<li><strong>MERGE JOIN<\/strong>: Eficiente para conjuntos de datos que ya est\u00e1n ordenados por las columnas de JOIN.<\/li>\n<li><strong>NESTED LOOP JOIN<\/strong>: Puede ser m\u00e1s eficiente cuando al menos uno de los conjuntos de datos es peque\u00f1o.<\/li>\n<\/ul>\n<h3>6. ANTI JOIN<\/h3>\n<p>No es un tipo de JOIN espec\u00edfico en SQL, pero puedes lograrlo usando LEFT JOIN con una cl\u00e1usula WHERE que filtra filas sin coincidencias. Devuelve las filas de la primera tabla que no tienen correspondencias en la segunda tabla.<\/p>\n<p>Cada uno de estos m\u00e9todos o t\u00e9cnicas tiene casos de uso espec\u00edficos y puede ser m\u00e1s adecuado para ciertas operaciones o consultas. La disponibilidad y el uso de estos dependen en gran medida del sistema de gesti\u00f3n de bases de datos espec\u00edfico que est\u00e9s utilizando.<\/p>\n<\/div>\n<p><a href=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/gestores.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-11241\" src=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/gestores.png\" alt=\"\" width=\"611\" height=\"629\" srcset=\"https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/gestores.png 611w, https:\/\/www.palentino.es\/blog\/wp-content\/uploads\/2024\/02\/gestores-291x300.png 291w\" sizes=\"auto, (max-width: 611px) 100vw, 611px\" \/><\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h1>Clasificaci\u00f3n seg\u00fan gestor<\/h1>\n<p>Clasificar los tipos de JOINs y t\u00e9cnicas relacionadas seg\u00fan su disponibilidad y uso en diferentes sistemas de gesti\u00f3n de bases de datos (DBMS) como SQL Server, MySQL, Oracle, y PostgreSQL puede ayudar a entender las capacidades espec\u00edficas de cada uno. A continuaci\u00f3n, se presenta una clasificaci\u00f3n basada en estos sistemas:<\/p>\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"relative flex w-full flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"mt-1 flex justify-start gap-3 empty:hidden\">\n<div class=\"text-gray-400 flex self-end lg:self-center justify-center lg:justify-start mt-0 -ml-1 visible\">\n<h3>SQL Server<\/h3>\n<ul>\n<li><strong>INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN<\/strong>: Disponibles en todas las versiones.<\/li>\n<li><strong>CROSS JOIN<\/strong>: Disponible.<\/li>\n<li><strong>NATURAL JOIN<\/strong>: No es soportado expl\u00edcitamente.<\/li>\n<li><strong>OUTER APPLY y CROSS APPLY<\/strong>: Espec\u00edficos de SQL Server, permiten unir tablas a funciones de tabla valoradas.<\/li>\n<li><strong>MERGE JOIN, HASH JOIN, NESTED LOOP JOIN<\/strong>: Estos son m\u00e9todos de ejecuci\u00f3n internos que el optimizador de SQL Server puede seleccionar, pero no son especificados directamente en las consultas.<\/li>\n<\/ul>\n<h3>MySQL<\/h3>\n<ul>\n<li><strong>INNER JOIN, LEFT JOIN, RIGHT JOIN<\/strong>: Disponibles en todas las versiones. MySQL utiliza LEFT JOIN y RIGHT JOIN para implementar las funcionalidades de OUTER JOIN.<\/li>\n<li><strong>CROSS JOIN<\/strong>: Disponible, a menudo equivalente a usar una coma para separar las tablas en la cl\u00e1usula FROM sin condici\u00f3n de uni\u00f3n.<\/li>\n<li><strong>FULL OUTER JOIN<\/strong>: No es soportado directamente, pero se puede simular con UNION de LEFT JOIN y RIGHT JOIN excluyendo las coincidencias.<\/li>\n<li><strong>NATURAL JOIN<\/strong>: Soportado, realiza joins autom\u00e1ticamente usando columnas con el mismo nombre en ambas tablas.<\/li>\n<\/ul>\n<h3>Oracle<\/h3>\n<ul>\n<li><strong>INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN<\/strong>: Disponibles en todas las versiones.<\/li>\n<li><strong>CROSS JOIN<\/strong>: Disponible.<\/li>\n<li><strong>NATURAL JOIN<\/strong>: Soportado.<\/li>\n<li><strong>HASH JOIN, MERGE JOIN, NESTED LOOP JOIN<\/strong>: Como en SQL Server, son m\u00e9todos de ejecuci\u00f3n internos que el optimizador de Oracle puede seleccionar, pero los desarrolladores pueden influir en la elecci\u00f3n mediante hints.<\/li>\n<\/ul>\n<h3>PostgreSQL<\/h3>\n<ul>\n<li><strong>INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN<\/strong>: Disponibles y ampliamente utilizados.<\/li>\n<li><strong>CROSS JOIN<\/strong>: Disponible.<\/li>\n<li><strong>NATURAL JOIN<\/strong>: Soportado.<\/li>\n<li><strong>LATERAL<\/strong>: Espec\u00edfico de PostgreSQL, permite subconsultas que pueden referenciar columnas de filas precedentes en la cl\u00e1usula FROM.<\/li>\n<li><strong>CROSS APPLY y OUTER APPLY<\/strong>: No son t\u00e9rminos utilizados en PostgreSQL, pero la funcionalidad de APPLY se puede lograr con LATERAL.<\/li>\n<li><strong>HASH JOIN, MERGE JOIN, NESTED LOOP JOIN<\/strong>: PostgreSQL tambi\u00e9n utiliza estos m\u00e9todos de ejecuci\u00f3n, y los desarrolladores pueden ofrecer sugerencias al optimizador mediante la configuraci\u00f3n de par\u00e1metros de planificaci\u00f3n.<\/li>\n<\/ul>\n<h3>Consideraciones Generales<\/h3>\n<ul>\n<li><strong>SELF JOIN<\/strong>: Disponible en todos los DBMS mencionados, ya que es m\u00e1s una t\u00e9cnica de modelado de consulta que un tipo de JOIN espec\u00edfico.<\/li>\n<li><strong>ANTI JOIN<\/strong>: Se puede implementar en todos los sistemas mediante LEFT JOIN con una cl\u00e1usula WHERE que busca filas sin coincidencias (por ejemplo,\n<div class=\"codecolorer-container text mac-classic\" style=\"overflow:auto;white-space:nowrap;width:635px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"text codecolorer\">WHERE table2.id IS NULL<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>).<\/li>\n<\/ul>\n<p>Esta clasificaci\u00f3n muestra que, mientras muchos tipos de JOIN y t\u00e9cnicas relacionadas son comunes a todos estos sistemas de bases de datos, hay caracter\u00edsticas y capacidades espec\u00edficas que var\u00edan entre ellos. Estas diferencias pueden influir en c\u00f3mo se dise\u00f1an y optimizan las consultas para cada sistema.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h1 class=\"flex\">Sobre el orden de operaci\u00f3n<\/h1>\n<div>En SQL, cuando se especifican m\u00faltiples JOINs en una consulta, el procesador de consultas eval\u00faa los JOINs en un orden basado en la l\u00f3gica de la consulta y el plan de ejecuci\u00f3n generado por el optimizador de consultas del sistema de gesti\u00f3n de bases de datos (DBMS). El orden de los JOINs en tu consulta puede influir en la legibilidad y, en algunos casos, en el rendimiento de la consulta, pero el resultado final de la consulta deber\u00eda ser el mismo, independientemente del orden en que se escriban los JOINs, debido a la naturaleza asociativa de los JOINs. Sin embargo, la forma en que se estructura la consulta puede afectar c\u00f3mo el optimizador elige ejecutarla.<\/div>\n<div>\n<h3>Orden L\u00f3gico de Procesamiento de una Consulta SQL<\/h3>\n<p>Aunque el optimizador de consultas determina el orden f\u00edsico de operaciones para ejecutar la consulta de manera eficiente, el orden l\u00f3gico de procesamiento de una consulta SQL es el siguiente:<\/p>\n<ol>\n<li><strong>FROM, incluyendo JOINs<\/strong>: Primero se determinan las tablas a consultar y c\u00f3mo se relacionan entre s\u00ed.<\/li>\n<li><strong>WHERE<\/strong>: Luego se filtran las filas seg\u00fan los criterios especificados.<\/li>\n<li><strong>GROUP BY<\/strong>: Despu\u00e9s se agrupan las filas resultantes seg\u00fan los campos especificados.<\/li>\n<li><strong>HAVING<\/strong>: Se filtran los grupos.<\/li>\n<li><strong>SELECT<\/strong>: Se seleccionan y se calculan las columnas especificadas.<\/li>\n<li><strong>ORDER BY<\/strong>: Finalmente, se ordenan las filas resultantes.<\/li>\n<\/ol>\n<h3>Evaluaci\u00f3n de los JOINs<\/h3>\n<p>Los JOINs se eval\u00faan de izquierda a derecha en el orden en que aparecen en la consulta, pero este es el orden l\u00f3gico. El optimizador de consultas puede cambiar este orden bas\u00e1ndose en estad\u00edsticas de uso, \u00edndices disponibles, y otros factores para mejorar el rendimiento. Esto es especialmente cierto en sistemas de bases de datos modernos donde el optimizador est\u00e1 muy avanzado.<\/p>\n<\/div>\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-38\">\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-40\">\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"relative flex w-full flex-col agent-turn\">\n<div class=\"absolute\">\n<div class=\"flex w-full gap-2 items-center justify-center\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-41\">\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"flex-shrink-0 flex flex-col relative items-end\">\n<div>\n<div class=\"pt-0.5\">\n<div class=\"gizmo-shadow-stroke flex h-6 w-6 items-center justify-center overflow-hidden rounded-full\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"relative flex w-full flex-col agent-turn\">\n<div class=\"flex-col gap-1 md:gap-3\">\n<div class=\"flex\"><\/div>\n<\/div>\n<div class=\"absolute\">\n<div class=\"flex w-full gap-2 items-center justify-center\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"w-full text-token-text-primary\" data-testid=\"conversation-turn-39\">\n<div class=\"px-4 py-2 justify-center text-base md:gap-6 m-auto\">\n<div class=\"flex flex-1 text-base mx-auto gap-3 md:px-5 lg:px-1 xl:px-5 md:max-w-3xl lg:max-w-[40rem] xl:max-w-[48rem] group\">\n<div class=\"flex-shrink-0 flex flex-col relative items-end\">\n<div>\n<div class=\"pt-0.5\">\n<div class=\"gizmo-shadow-stroke flex h-6 w-6 items-center justify-center overflow-hidden rounded-full\"><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Las relaciones entre tablas en una base de datos SQL son fundamentales para organizar y acceder a los datos de manera eficiente. Estas relaciones se establecen mediante el uso de claves primarias (Primary Keys, PK) y claves for\u00e1neas (Foreign Keys, FK), permitiendo modelar las interacciones entre los diferentes conjuntos de datos. Existen tres tipos principales de relaciones: Uno a Uno (1:1), Uno a Muchos (1:N) y Muchos a Muchos (M:N). Veamos cada una en detalle: &nbsp; Las relaciones entre tablas en una base de datos SQL son fundamentales para organizar y acceder a los datos de manera eficiente. Estas relaciones se establecen mediante el uso de claves primarias (Primary Keys, PK) y claves for\u00e1neas (Foreign Keys, FK), permitiendo modelar las interacciones entre los diferentes conjuntos de datos. Existen tres tipos principales de relaciones: Uno a Uno (1:1), Uno a Muchos (1:N) y Muchos a Muchos (M:N). Veamos cada una en detalle:<\/p>\n","protected":false},"author":1,"featured_media":11239,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1415,295],"tags":[],"class_list":["post-11230","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sin-categoria-es","category-sql-2"],"_links":{"self":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/11230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/comments?post=11230"}],"version-history":[{"count":11,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/11230\/revisions"}],"predecessor-version":[{"id":11244,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/posts\/11230\/revisions\/11244"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/media\/11239"}],"wp:attachment":[{"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/media?parent=11230"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/categories?post=11230"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.palentino.es\/blog\/wp-json\/wp\/v2\/tags?post=11230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}