98917 VISITAS ACERCA ARCHIVOS BLOG FOTOS PROYECTOS

INNER JOIN, LEFT OUTER JOIN y RIGHT OUTER JOIN en MySQL Explicado Con Diptongos y Hiatos

Hola, hoy platicaremos un poco de Joins (Uniones) en MySQL. Y de paso podemos repasar que son los diptongos, hiatos y triptongos.

Para los ejemplos, necesitamos crear y llenar tres tablas. La primera es un catálogo de las reglas gramaticales para los acentos:

CREATE TABLE regla (
	idRegla VARCHAR(1) DEFAULT '' PRIMARY KEY,
	nombre VARCHAR(20) DEFAULT '' NOT NULL,
	descripcion VARCHAR(250) DEFAULT '' NOT NULL
);

INSERT INTO regla VALUES ('A','aguda','última sílaba');
INSERT INTO regla VALUES ('G','grave','penúltima sílaba');
INSERT INTO regla VALUES ('E','esdrújula','antepenúltima sílaba');
INSERT INTO regla VALUES ('S','sobreesdrújula','trasantepenúltima sílaba');

La segunda tabla es un catálogo de casos especiales, tales como diptongo, hiato y triptongo.

CREATE TABLE caso (
	idCaso VARCHAR(1) DEFAULT '' PRIMARY KEY,
	nombre VARCHAR(20) DEFAULT '' NOT NULL,
	descripcion VARCHAR(250) DEFAULT '' NOT NULL
);

INSERT INTO caso VALUES ('H','hiato','dos vocales fuertes están juntas | una vocal fuerte está junto con una vocal débil que suena más fuerte (en este caso siempre se acentúa la vocal débil)');
INSERT INTO caso VALUES ('D','diptongo','');
INSERT INTO caso VALUES ('T','triptongo','');

Y la tercera tabla almacena las palabras que vamos a estudiar.

CREATE TABLE palabra (
	cadena VARCHAR(20) DEFAULT '' PRIMARY KEY,
	idRegla VARCHAR(1) NULL,
	idCaso VARCHAR(1) NULL,
	FOREIGN KEY (idRegla) REFERENCES regla (idRegla),
	FOREIGN KEY (idCaso) REFERENCES caso (idCaso)
);

INSERT INTO palabra VALUES ('Raúl','A','H');
INSERT INTO palabra VALUES ('baúl','A','H');
INSERT INTO palabra VALUES ('bahía','G','H');
INSERT INTO palabra VALUES ('tía','G','H');
INSERT INTO palabra VALUES ('aéreo','E','H');
INSERT INTO palabra VALUES ('canción','A','D');
INSERT INTO palabra VALUES ('estuvo','G',NULL);
INSERT INTO palabra VALUES ('país','A','H');
INSERT INTO palabra VALUES ('maíz','A','H');

INSERT INTO palabra VALUES ('nunca','G',NULL);
INSERT INTO palabra VALUES ('jamás','A',NULL);

INSERT INTO palabra VALUES ('quiero','G','T');
INSERT INTO palabra VALUES ('ver',NULL,NULL);
INSERT INTO palabra VALUES ('tu',NULL,NULL);
INSERT INTO palabra VALUES ('risa','G',NULL);
INSERT INTO palabra VALUES ('todo','G',NULL);
INSERT INTO palabra VALUES ('el',DEFAULT,DEFAULT);
INSERT INTO palabra VALUES ('día','G','H');

Si seleccionamos todas las palabras tenemos 18 filas.

SELECT *
FROM palabra;

Si seleccionamos todas las palabras que no tiene una regla gramatical tenemos 3 filas.

SELECT *
FROM palabra
WHERE idRegla IS NULL;

[INNER] JOIN


INNER JOIN con teoría de conjuntos.

Seleccionamos sólo las palabras que tienen regla gramatical.

-- 15 rows (sólo palabras con regla)
SELECT p.cadena, r.nombre
FROM palabra AS p
INNER JOIN regla AS r ON p.idRegla = r.idRegla;

Entonces tenemos 15 filas.

cadena  nombre
------- ------
baúl    aguda
canción aguda
jamás   aguda
maíz    aguda
país    aguda
Raúl    aguda
aéreo   esdrújula
bahía   grave
día     grave
estuvo  grave
nunca   grave
quiero  grave
risa    grave
tía     grave
todo    grave

LEFT [OUTER] JOIN


LEFT OUTER JOIN con teoría de conjuntos.

Ahora seleccionamos todas las palabras aunque no tengan regla gramatical.

-- 18 rows (todas las palabras, aunque no tengan regla)
SELECT p.cadena, r.nombre
FROM palabra AS p
LEFT OUTER JOIN regla AS r ON p.idRegla = r.idRegla;

Entonces tenemos 18 filas.

cadena  nombre
------- ------
el
tu
ver
baúl    aguda
canción aguda
jamás   aguda
maíz    aguda
país    aguda
Raúl    aguda
aéreo   esdrújula
bahía   grave
día     grave
estuvo  grave
nunca   grave
quiero  grave
risa    grave
tía     grave
todo    grave

RIGHT [OUTER] JOIN


RIGHT OUTER JOIN con teoría de conjuntos.

Ahora seleccionamos todas las reglas gramaticales aunque no existan palabras asociadas.

-- 16 rows (15 palabras con regla + 1 regla sin palabras)
SELECT p.cadena, r.nombre
FROM palabra AS p
RIGHT OUTER JOIN regla AS r ON p.idRegla = r.idRegla;

Entonces tenemos 16 filas.

cadena  nombre
------- ------
baúl    aguda
canción aguda
jamás   aguda
maíz    aguda
país    aguda
Raúl    aguda
aéreo   esdrújula
bahía   grave
día     grave
estuvo  grave
nunca   grave
quiero  grave
risa    grave
tía     grave
todo    grave
        sobreesdrújula

NATURAL JOIN


El NATURAL JOIN nos ahorra la fastidiosa tarea de escribir las condiciones ON .. si hemos trabajado correctamente con las llaves primarias (PRIMARY KEY) y las llaves foraneas (FOREIGN KEY).

Así que podemos reescribir las consultas anteriores usando la sintaixs del NATURAL JOIN.

-- 15 rows (sólo palabras con regla)
SELECT p.cadena, r.nombre
FROM palabra AS p
NATURAL JOIN regla AS r;

-- 18 rows (todas las palabras, aunque no tengan regla)
SELECT p.cadena, r.nombre
FROM palabra AS p
NATURAL LEFT OUTER JOIN regla AS r;

-- 16 rows (15 palabras con regla + 1 regla sin palabras)
SELECT p.cadena, r.nombre
FROM palabra AS p
NATURAL RIGHT OUTER JOIN regla AS r;

Conclusiones


La posible salida deseada con estas tres tablas puede ser esta.

-- 18 rows (todas la palabras, con su regla y caso si estás aplican)
SELECT p.cadena AS cadena, IFNULL(r.nombre,) AS regla, IFNULL(c.nombre,) AS caso
FROM palabra p
LEFT OUTER JOIN regla r ON p.idRegla = r.idRegla
LEFT OUTER JOIN caso c ON p.idCaso = c.idCaso;

Entonces tenenemos 18 filas.

cadena  regla       caso
------- ----------- ----
aéreo   esdrújula   hiato
bahía   grave       hiato
baúl    aguda       hiato
canción aguda       diptongo
día     grave       hiato
el
estuvo  grave
jamás   aguda
maíz    aguda       hiato
nunca   grave
país    aguda       hiato
quiero  grave       triptongo
Raúl    aguda       hiato
risa    grave
tía     grave       hiato
todo    grave
tu

CREATE VIEW


Podemos generar una vista de la consulta anterior.

CREATE VIEW gramatica AS
SELECT p.cadena AS cadena, IFNULL(r.nombre,) AS regla, IFNULL(c.nombre,) AS caso
FROM palabra p
LEFT OUTER JOIN regla r ON p.idRegla = r.idRegla
LEFT OUTER JOIN caso c ON p.idCaso = c.idCaso;

Ahora tenemos una consulta más sencilla.

SELECT *
FROM gramatica;

publicado el 24 de mayo de 2008 a las 12:04

Advertencia

La información de esta página no es confiable. El conocimiento se adquirió de forma empírica (o por fuerza bruta) y algunos términos pudieron ser inventados. Los trucos mencionados en este blog difícilmente son la manera más eficiente de resolver algún problema. La información no se actualiza y tampoco proviene de fuentes oficiales. Mejor acérquese a la documentación oficial, compre libros o visite la Wikipedia.

Comentarios Y Quejas Aquí






usa gravatar.com

Oskr!

Excelente explicación del INNER JOIN, LEFT OUTER JOIN y RIGHT OUTER JOIN, muchas personas no lo entendemos a la primera, pero creo que con esto, es mucho muy sencillo.

Para completar el artículo, faltaría explicar el CROSS JOIN, aunque en estos momentos estoy pensando si existe en MySQL..

publicado el 8 de junio de 2008 a las 23:57

Claro que existe el CROSS JOIN.

-- CROSS JOIN
-- 64 rows (el producto cartesiano, todas las palabras con todas las reglas)
-- obviamente no lleva la sentencia ON
SELECT p.cadena, r.nombre
FROM palabra AS p
CROSS JOIN regla AS r;

publicado el 9 de junio de 2008 a las 22:24

Muy buen artículo.
Bien explicado.

publicado el 15 de agosto de 2008 a las 13:18

usa gravatar.com

ricchell

exelente trabajo voy a seguir praticando
te lo digo
ciudad es diptongo aberiguais triptongo ahereo es hiato es bueno estuiar todo lo que te den en el colegio

publicado el 5 de noviembre de 2008 a las 20:08

usa gravatar.com

Fredy

Como selecionar solo los registros de tabla PALABRA, que no estan en Tabla Regla

publicado el 6 de noviembre de 2008 a las 11:50

Fredy, para seleccionar las palabras sin regla, podemos buscar las filas que tengan un valor NULL en la columna idRegla.

SELECT *
FROM palabra
WHERE idRegla IS NULL;

publicado el 6 de noviembre de 2008 a las 22:12

usa gravatar.com

luis

hola, ojala y puedan ayudarme, tengo un problema con left join, les explico y repito ojala alguien pueda ayudarme.

tengo 4 tablas,
importe([No Folio],Importe)
pago ([No Folio],Pago,[Fecha Pago])
abono ([No Folio],Abono,[Fecha Abono])
Liquidacion ([No Folio],Liquidacion,[Fecha Liquidacion])

necesito que me de algo asi

Folio Importe Pago Abono Liquidacion
001 1000 500 500
002 800 800

ya logre hacer eso y sale muy bien, les dejo la consulta:

SELECT Importe.[No Folio], Importe.Importe, Pago.[Pago Total], Abono.Abono, Liquidacion.Liquidacion FROM (((Importe LEFT JOIN Pago ON Importe.[No Folio]= Pago.[No Folio])LEFT JOIN Abono ON Importe.[No Folio]= Abono.[No Folio]) LEFT JOIN Liquidacion ON Importe.[No Folio]= Liquidacion.[No Folio])


ahora no se como poner que solo me de, cuando cada una de las fechas de cada tabla sea igual a una fecha k yo ponga

ejem. 05/12/2008
que me haga lo k puse antes pero solo que sea con esa fecha , no c donde colocar la condicion.

gracias, ah, por si sirve de algo, es una consulta en visual basic 6 en access

publicado el 8 de diciembre de 2008 a las 2:05

usa gravatar.com

luis

no salio bien esto


necesito que me de algo asi

Folio Importe - Pago - Abono - Liquidacion
001 ---1000 -- Nulo -- 500 --- 500
002 --- 800 ---- 800 ----Nulo ----Nulo

publicado el 8 de diciembre de 2008 a las 2:07

Mmm así le puedes agregar que te muestre las uniones de determinada fecha:

SELECT Importe.[No Folio], Importe.Importe, Pago.[Pago Total], Abono.Abono, Liquidacion.Liquidacion
FROM Importe
LEFT JOIN Pago ON Importe.[No Folio] = Pago.[No Folio]
LEFT JOIN Abono ON Importe.[No Folio] = Abono.[No Folio]
LEFT JOIN Liquidacion ON Importe.[No Folio] = Liquidacion.[No Folio]
WHERE Pago.[Fecha Pago] = '2008-12-05'
AND Abono.[Fecha Abono] = '2008-12-05'
AND Liquidacion.[Fecha Liquidacion] = '2008-12-05';

publicado el 8 de diciembre de 2008 a las 6:52

usa gravatar.com

Luis

gracias gilberto por contestarme, ve ya prove lo que dices, pero no da resultados, pero tampoco marka error, ve como quedo ahora

SELECT Importe.[No Folio], Importe.Importe, Pago.[Pago Total], Abono.Abono, Liquidacion.Liquidacion FROM (((Importe LEFT JOIN Pago ON Importe.[No Folio]= Pago.[No Folio])LEFT JOIN Abono ON Importe.[No Folio]= Abono.[No Folio]) LEFT JOIN Liquidacion ON Importe.[No Folio]= Liquidacion.[No Folio]) WHERE Pago.[Fecha Pago] = '09/12/2008' AND Abono.[Fecha Abono] = '09/12/2008' AND Liquidacion.[Fecha Liquidacion] = '09/12/2008'"

las fechas las acomode asi, xk las manejo primero el dia y al final el año, pero ve

esta fecha la tengo k colocar en 3 texts, primero el dia, mes , año, luego dar en el boton.

clave = Text1.Text & Label1.Caption & Text2.Text & Label1.Caption & Text3.Text

el label es = / xk la fecha la tengo con 07/12/2008.

y pus ya intente algo como [Fecha Abono] = '" & clave & "' en cada fecha, pero no da resultados, pero aka si marka error.

asi como t la mostre al inicio, si le kito los parentesis me da error.

publicado el 9 de diciembre de 2008 a las 3:17

Hola Luis.

Los paréntesis que pones no son necesario, mejor quítalos y asegúrate de poner espacios entre las palabras. ¿Qué errores marca? ¡Copia y pega los errores aquí!

Estas seguro del formato de fecha que usa el servidor de SQL? Puedes comprobarlo con la siguiente sentencia:

SELECT GETDATE();

A mí me da un resultado así, pero depende de cada configuración:

2008-12-09 17:31:52.653

Y el script así es correcto:

SELECT Importe.[No Folio], Importe.Importe, Pago.[Pago Total], Abono.Abono, Liquidacion.Liquidacion
FROM Importe LEFT JOIN Pago ON Importe.[No Folio] = Pago.[No Folio]
LEFT JOIN Abono ON Importe.[No Folio] = Abono.[No Folio]
LEFT JOIN Liquidacion ON Importe.[No Folio]= Liquidacion.[No Folio]
WHERE Pago.[Fecha Pago] = '09/12/2008'
AND Abono.[Fecha Abono] = '09/12/2008'
AND Liquidacion.[Fecha Liquidacion] = '09/12/2008';

publicado el 9 de diciembre de 2008 a las 17:37

usa gravatar.com

Luis

ojala tengas paciencia gilberto, ve ya le quite los parentesis y revise de darle el espacio a las palabras, y me da el siguiente error

Error '3075' en tiempo de ejecucion
error de sintaxis(falta operador) en la expresion de consulta

y no entedi bien eso del SELECT GETDATE();
toy manejando access
pero si checo la fecha y hora de como me lo da el sistema
es asi

09/12/2008 10:45:05 p.m.

te dejo completa la consulta

Data1.RecordSource = ("SELECT Importe.[No Folio], Importe.Importe, Pago.[Pago Total], Abono.Abono, Liquidacion.Liquidacion FROM Importe LEFT JOIN Pago ON Importe.[No Folio] = Pago.[No Folio] LEFT JOIN Abono ON Importe.[No Folio] = Abono.[No Folio] LEFT JOIN Liquidacion ON Importe.[No Folio] = Liquidacion.[No Folio] WHERE Pago.[Fecha Pago] = '09/12/2008' AND Abono.[Fecha Abono] = '09/12/2008' AND Liquidacion.[Fecha Liquidacion] = '09/12/2008'")

Data1.Refresh

publicado el 9 de diciembre de 2008 a las 22:50