Ejer Alg relacional

Iniciado por rubcr, 15 Abril 2020, 20:34 PM

0 Miembros y 2 Visitantes están viendo este tema.

rubcr

Buenas tardes a todos, tengo un ejercicio de álgebra relacional que ya he resuelto pero no estoy seguro si está completamente bien resuelto.
Es el siguiente:

Ejercicio. Se pide conocer el nombre de los Proveedores que han suministrado artículos de color rojo y verde dadas las siguientes tablas:

PROVEEDORES(#Cod_Prov, Nombre, Ciudad, Calle, Número)
ARTÍCULOS(#Cod_Art, Nombre_a, Precio, Descr, Color)
PEDIDOS(#Cod_Prov, #Cod_Art, Cantidad)

*Para la realización del ejercicio se prohíbe el uso de condiciones complejas en las selecciones, es decir, se permiten operaciones como σ(nombre=Federico)(PERSONAS) pero está prohibido usar expresiones del tipo σ(nombre="Federico" ⋀ ciudad="Madrid")(PERSONAS).

Mi solución es la siguiente:
πNombre(Proveedores *(σCOLOR='ROJO'(Artículos)) ∩ πNombre(Proveedores *(σCOLOR='VERDE'(Artículos))
Espero que alguien pueda ayudarme, un saludo.

K-YreX

No es correcta esa solución. Te pongo un ejemplo para que lo veas:

PROVEEDORES:
P1 NombreP1 CiudadP1 ...
P2 NombreP2 CiudadP2 ...
P3 NombreP3 CiudadP3 ...


ARTICULOS:
A1 NombreA1 Rojo ...
A2 NombreA2 Verde ...
A3 NombreA3 Azul ...


Con el supuesto de los registros descritos arriba, tu primera parte de la intersección obtiene 3 registros (filas) cogiendo el artículo A1 y pegándole cada uno de los proveedores.

RESULTADO R1 = (Proveedores * Sigma(Color = 'Rojo')(Articulos)):
P1 NombreP1 ... A1 NombreA1 Rojo ...
P2 NombreP2 ... A1 NombreA1 Rojo ...
P3 NombreP3 ... A1 NombreA1 Rojo ...


Luego coges el nombre de cada proveedor:

RESULTADO R2 = PI(nombre)(R1):
NombreP1
NombreP2
NombreP3

Es decir que tus operaciones siempre devuelven el nombre de todos los proveedores. En ningún momento compruebas que ese proveedor haya solicitado ese artículo. Para hacer esto es para lo que tienes la relación PEDIDOS que relaciona los proveedores con los artículos. Es fácil ver esto porque es la relación que relaciona los códigos de una con los códigos de la otra y debes usar esta condición para filtrar los productos.

Lo que tienes que hacer es coger los artículos de color Rojo:

R1 = Sigma(color = 'Rojo')(Artículos)

Relacionarlo con la tabla/relación PEDIDOS con el fin de obtener los Cod_prov de los proveedores que tengan algún pedido con esos artículos:

R2 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(PEDIDOS x R1)

Y ahora relacionar este resultado R2 con la tabla PROVEEDORES para sacar los nombres asociados a cada Cod_prov que tenemos:

R3 = Sigma(Proveedores.Cod_prov = R2.Cod_prov)(Proveedores x R2)

Y ahora nos quedamos solo con los nombres:

R4 = PI(Nombre)(R3)


Con eso ya tienes los nombres de los proveedores que han suministrado artículos de color rojo. Te quedaría hacer lo mismo para los de color verde. Es más fácil si lo vas haciendo por partes como te he puesto yo aquí porque te quedan consultas más cortas.

Hazlo detenidamente y en caso de duda siempre puedes ponerte un ejemplo pequeño con 3 tablas y ver lo que va saliendo. Cualquier duda que tengas no dudes en comentar.
PD: Si utilizas tablas de ejemplo que sean pequeñas porque cada vez que multiplicas dos tablas A y B con un número de filas #A = n y #B = m, tendrás una tabla resultado C con un número de filas #C = m*n por lo que las tablas crecerán muy rápido de número de filas.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

Cita de: YreX-DwX en 15 Abril 2020, 22:01 PM
No es correcta esa solución. Te pongo un ejemplo para que lo veas:

PROVEEDORES:
P1 NombreP1 CiudadP1 ...
P2 NombreP2 CiudadP2 ...
P3 NombreP3 CiudadP3 ...


ARTICULOS:
A1 NombreA1 Rojo ...
A2 NombreA2 Verde ...
A3 NombreA3 Azul ...


Con el supuesto de los registros descritos arriba, tu primera parte de la intersección obtiene 3 registros (filas) cogiendo el artículo A1 y pegándole cada uno de los proveedores.

RESULTADO R1 = (Proveedores * Sigma(Color = 'Rojo')(Articulos)):
P1 NombreP1 ... A1 NombreA1 Rojo ...
P2 NombreP2 ... A1 NombreA1 Rojo ...
P3 NombreP3 ... A1 NombreA1 Rojo ...


Luego coges el nombre de cada proveedor:

RESULTADO R2 = PI(nombre)(R1):
NombreP1
NombreP2
NombreP3

Es decir que tus operaciones siempre devuelven el nombre de todos los proveedores. En ningún momento compruebas que ese proveedor haya solicitado ese artículo. Para hacer esto es para lo que tienes la relación PEDIDOS que relaciona los proveedores con los artículos. Es fácil ver esto porque es la relación que relaciona los códigos de una con los códigos de la otra y debes usar esta condición para filtrar los productos.

Lo que tienes que hacer es coger los artículos de color Rojo:

R1 = Sigma(color = 'Rojo')(Artículos)

Relacionarlo con la tabla/relación PEDIDOS con el fin de obtener los Cod_prov de los proveedores que tengan algún pedido con esos artículos:

R2 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(PEDIDOS x R1)

Y ahora relacionar este resultado R2 con la tabla PROVEEDORES para sacar los nombres asociados a cada Cod_prov que tenemos:

R3 = Sigma(Proveedores.Cod_prov = R2.Cod_prov)(Proveedores x R2)

Y ahora nos quedamos solo con los nombres:

R4 = PI(Nombre)(R3)


Con eso ya tienes los nombres de los proveedores que han suministrado artículos de color rojo. Te quedaría hacer lo mismo para los de color verde. Es más fácil si lo vas haciendo por partes como te he puesto yo aquí porque te quedan consultas más cortas.

Hazlo detenidamente y en caso de duda siempre puedes ponerte un ejemplo pequeño con 3 tablas y ver lo que va saliendo. Cualquier duda que tengas no dudes en comentar.
PD: Si utilizas tablas de ejemplo que sean pequeñas porque cada vez que multiplicas dos tablas A y B con un número de filas #A = n y #B = m, tendrás una tabla resultado C con un número de filas #C = m*n por lo que las tablas crecerán muy rápido de número de filas.



Gracias por responder.
Comprendo lo que explicas, pero al intentar realizar la fórmula completa no soy capaz de plasmar lo que has expuesto

K-YreX

Cita de: rubcr en 15 Abril 2020, 22:23 PM
Gracias por responder.
Comprendo lo que explicas, pero al intentar realizar la fórmula completa no soy capaz de plasmar lo que has expuesto
Si entiendes lo que he ido haciendo por partes, al final solo tienes que juntarlo, es decir, donde pone R3 pones toda la expresión de R3 y te quedará un R2 que tendrás que sustituir por R2 y lo mismo con R1 y ya tendrás la fórmula completa.
No sé si es ese tu problema.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

Cita de: YreX-DwX en 15 Abril 2020, 22:30 PM
Si entiendes lo que he ido haciendo por partes, al final solo tienes que juntarlo, es decir, donde pone R3 pones toda la expresión de R3 y te quedará un R2 que tendrás que sustituir por R2 y lo mismo con R1 y ya tendrás la fórmula completa.
No sé si es ese tu problema.

Código:
R2 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(PEDIDOS x R1)
En esta parte en concreto que significa el . entre medias y por qué hay un igual y un símbolo de multiplicar
No comprendo lo que significa.

K-YreX

Cita de: rubcr en 15 Abril 2020, 22:38 PM
Código:
R2 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(PEDIDOS x R1)
En esta parte en concreto que significa el . entre medias y por qué hay un igual y un símbolo de multiplicar
No comprendo lo que significa.
El símbolo de multiplicar es igual que lo que habías puesto tú pero tú has usado un asterisco (*) y yo he usado una x. Es un producto cartesiano, es decir, que el resultado de hacer un producto entre dos tablas es una tabla nueva en la que relacionas cada fila de la primera tabla con cada fila de la segunda tabla.

Tabla 1:
a1 a2
a3 a4

Tabla 2:
b1 b2
b3 b4

Resultado de Tabla1 x Tabla2:
a1 a2 b1 b2
a1 a2 b3 b4
a3 a4 b1 b2
a3 a4 b3 b4


Lo que queremos con eso es juntar en una misma fila los campos de la tabla Pedidos con los campos de la tabla Artículos. Pero si tenemos la siguiente situación:

PEDIDOS (#Cod_prov, #Cod_art, Cantidad):
P1 A1 5
P1 A2 8
P2 A1 3
P2 A3 1

ARTICULOS (#Cod_art, Nombre, Color):
A1 NombreA1 Rojo
A2 NombreA2 Verde
A3 NombreA3 Azul


Si hacemos el producto de PEDIDOS x ARTICULOS sin más obtenemos:

P1 A1 5 A1 NombreA1 Rojo
P1 A1 5 A2 NombreA2 Verde
P1 A1 5 A3 NombreA3 Azul
P1 A2 8 A1 NombreA1 Rojo
P1 A2 8 A2 NombreA2 Verde
P1 A2 8 A3 NombreA3 Azul
P2 A1 3 A1 NombreA1 Rojo
P2 A1 3 A2 NombreA2 Verde
P2 A1 3 A3 NombreA3 Azul
P2 A3 1 A1 NombreA1 Rojo
P2 A3 1 A2 NombreA2 Verde
P2 A3 1 A3 NombreA3 Azul

Pero como puedes imaginar no tiene sentido juntar en (por ejemplo) la segunda fila un pedido del Artículo A1 con los datos del Artículo A2. Entonces de todas estas filas las únicas que tienen sentido son las que ambos códigos de artículo (tanto el de PEDIDOS como el de ARTICULOS) coincide. Para esto se usa el operador =. Queremos que el Cod_art de Pedidos sea igual al Cod_art de Artículos. Como ambos campos se llaman igual para diferenciar el de una tabla y el de la otra, se pone delante la tabla a la que pertenece.
R1 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(Pedidos x Articulos) da como resultado:

P1 A1 5 A1 NombreA1 Rojo
P1 A2 8 A2 NombreA2 Verde
P2 A1 3 A1 NombreA1 Rojo
P2 A3 1 A3 NombreA3 Azul

Entonces el proveedor P1 ha suministrado el artículo A1 que es rojo y el artículo A2 que es verde. El proveedor P2 ha suministrado el artículo A1 también que es rojo y el artículo A3 que es Azul. Pero no nos vale con saber el código del proveedor P1, P2,... sino que queremos su nombre.

Para tener el nombre de los proveedores tenemos que volver a "mezclar" las 4 filas de arriba con la tabla Proveedores que por ejemplo es:

PROVEEDORES(#Cod_prov, Nombre):
P1 NombreP1
P2 NombreP2


Y el resultado de hacer otro producto cartesiano entre PROVEEDORES x R1 (que es la tabla anterior) sin más sería:

P1 A1 5 A1 NombreA1 Rojo P1 NombreP1
P1 A1 5 A1 NombreA1 Rojo P2 NombreP2
P1 A2 8 A2 NombreA2 Verde P1 NombreP1
P1 A2 8 A2 NombreA2 Verde P2 NombreP2
P2 A1 3 A1 NombreA1 Rojo P1 NombreP1
P2 A1 3 A1 NombreA1 Rojo P2 NombreP2
P2 A3 1 A3 NombreA3 Azul P1 NombreP1
P2 A3 1 A3 NombreA3 Azul P2 NombreP2

Pero por lo mismo de antes, no tiene sentido juntar un pedido del proveedor P1 con los datos del proveedor P2 (cosa que pasa por ejemplo en la segunda fila). Para eso se vuelve a poner la condición de que los Cod_prov de cada uno sean iguales.
R2 = Sigma(R1.Cod_prov = Proveedor.Cod_prov)(R1 x Proveedor):

P1 A1 5 A1 NombreA1 Rojo P1 NombreP1
P1 A2 8 A2 NombreA2 Verde P1 NombreP1
P2 A1 3 A1 NombreA1 Rojo P2 NombreP2
P2 A3 1 A3 NombreA3 Azul P2 NombreP2


Ahora: Nombre de los proveedores que suministran artículos rojos. Pues de la tabla R2 que tenemos justo encima cogemos con Sigma() las filas cuyo Color es Verde (por ejemplo) y de ahí mostramos con PI() el Nombre del proveedor.
RFinal1 = PI(NombreProveedor)(Sigma(Color = 'Verde')(R2):

NombreP1

El proveedor con nombre NombreP1 es el único que suministra algún artículo Verde.

Hacemos lo mismo con el Rojo:
RFinal2 = PI(NombreProveedor)(Sigma(Color = 'Rojo')(R2):

NombreP1
NombreP2

Tanto el proveedor NombreP1 como NombreP2 suministran algún artículo de color Rojo.

Si queremos saber los que suministran artículos tanto de color Verde como Rojo hacemos la intersección de ambos, es decir, los nombres que estén tanto en RFinal1 como en RFinal2.
RFinal = RFinal1 INTERSECCION RFinal2:

NombreP1
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

Cita de: YreX-DwX en 15 Abril 2020, 23:01 PM
El símbolo de multiplicar es igual que lo que habías puesto tú pero tú has usado un asterisco (*) y yo he usado una x. Es un producto cartesiano, es decir, que el resultado de hacer un producto entre dos tablas es una tabla nueva en la que relacionas cada fila de la primera tabla con cada fila de la segunda tabla.

Tabla 1:
a1 a2
a3 a4

Tabla 2:
b1 b2
b3 b4

Resultado de Tabla1 x Tabla2:
a1 a2 b1 b2
a1 a2 b3 b4
a3 a4 b1 b2
a3 a4 b3 b4


Lo que queremos con eso es juntar en una misma fila los campos de la tabla Pedidos con los campos de la tabla Artículos. Pero si tenemos la siguiente situación:

PEDIDOS (#Cod_prov, #Cod_art, Cantidad):
P1 A1 5
P1 A2 8
P2 A1 3
P2 A3 1

ARTICULOS (#Cod_art, Nombre, Color):
A1 NombreA1 Rojo
A2 NombreA2 Verde
A3 NombreA3 Azul


Si hacemos el producto de PEDIDOS x ARTICULOS sin más obtenemos:

P1 A1 5 A1 NombreA1 Rojo
P1 A1 5 A2 NombreA2 Verde
P1 A1 5 A3 NombreA3 Azul
P1 A2 8 A1 NombreA1 Rojo
P1 A2 8 A2 NombreA2 Verde
P1 A2 8 A3 NombreA3 Azul
P2 A1 3 A1 NombreA1 Rojo
P2 A1 3 A2 NombreA2 Verde
P2 A1 3 A3 NombreA3 Azul
P2 A3 1 A1 NombreA1 Rojo
P2 A3 1 A2 NombreA2 Verde
P2 A3 1 A3 NombreA3 Azul

Pero como puedes imaginar no tiene sentido juntar en (por ejemplo) la segunda fila un pedido del Artículo A1 con los datos del Artículo A2. Entonces de todas estas filas las únicas que tienen sentido son las que ambos códigos de artículo (tanto el de PEDIDOS como el de ARTICULOS) coincide. Para esto se usa el operador =. Queremos que el Cod_art de Pedidos sea igual al Cod_art de Artículos. Como ambos campos se llaman igual para diferenciar el de una tabla y el de la otra, se pone delante la tabla a la que pertenece.
R1 = Sigma(Pedidos.Cod_art = Articulos.Cod_art)(Pedidos x Articulos) da como resultado:

P1 A1 5 A1 NombreA1 Rojo
P1 A2 8 A2 NombreA2 Verde
P2 A1 3 A1 NombreA1 Rojo
P2 A3 1 A3 NombreA3 Azul

Entonces el proveedor P1 ha suministrado el artículo A1 que es rojo y el artículo A2 que es verde. El proveedor P2 ha suministrado el artículo A1 también que es rojo y el artículo A3 que es Azul. Pero no nos vale con saber el código del proveedor P1, P2,... sino que queremos su nombre.

Para tener el nombre de los proveedores tenemos que volver a "mezclar" las 4 filas de arriba con la tabla Proveedores que por ejemplo es:

PROVEEDORES(#Cod_prov, Nombre):
P1 NombreP1
P2 NombreP2


Y el resultado de hacer otro producto cartesiano entre PROVEEDORES x R1 (que es la tabla anterior) sin más sería:

P1 A1 5 A1 NombreA1 Rojo P1 NombreP1
P1 A1 5 A1 NombreA1 Rojo P2 NombreP2
P1 A2 8 A2 NombreA2 Verde P1 NombreP1
P1 A2 8 A2 NombreA2 Verde P2 NombreP2
P2 A1 3 A1 NombreA1 Rojo P1 NombreP1
P2 A1 3 A1 NombreA1 Rojo P2 NombreP2
P2 A3 1 A3 NombreA3 Azul P1 NombreP1
P2 A3 1 A3 NombreA3 Azul P2 NombreP2

Pero por lo mismo de antes, no tiene sentido juntar un pedido del proveedor P1 con los datos del proveedor P2 (cosa que pasa por ejemplo en la segunda fila). Para eso se vuelve a poner la condición de que los Cod_prov de cada uno sean iguales.
R2 = Sigma(R1.Cod_prov = Proveedor.Cod_prov)(R1 x Proveedor):

P1 A1 5 A1 NombreA1 Rojo P1 NombreP1
P1 A2 8 A2 NombreA2 Verde P1 NombreP1
P2 A1 3 A1 NombreA1 Rojo P2 NombreP2
P2 A3 1 A3 NombreA3 Azul P2 NombreP2


Ahora: Nombre de los proveedores que suministran artículos rojos. Pues de la tabla R2 que tenemos justo encima cogemos con Sigma() las filas cuyo Color es Verde (por ejemplo) y de ahí mostramos con PI() el Nombre del proveedor.
RFinal1 = PI(NombreProveedor)(Sigma(Color = 'Verde')(R2):

NombreP1

El proveedor con nombre NombreP1 es el único que suministra algún artículo Verde.

Hacemos lo mismo con el Rojo:
RFinal2 = PI(NombreProveedor)(Sigma(Color = 'Rojo')(R2):

NombreP1
NombreP2

Tanto el proveedor NombreP1 como NombreP2 suministran algún artículo de color Rojo.

Si queremos saber los que suministran artículos tanto de color Verde como Rojo hacemos la intersección de ambos, es decir, los nombres que estén tanto en RFinal1 como en RFinal2.
RFinal = RFinal1 INTERSECCION RFinal2:

NombreP1


Si me pudieses poner lo que es la operación entera te lo agradecería de verdad, lo que es la teoría lo entiendo pero lo demás no lo comprendo.

K-YreX

#7
Cita de: rubcr en 15 Abril 2020, 23:12 PM
Si me pudieses poner lo que es la operación entera te lo agradecería de verdad, lo que es la teoría lo entiendo pero lo demás no lo comprendo.
Te he puesto la operación entera pero explicada por partes tanto con teoría como con ejemplos para que se vea lo que hace cada cosa.
Que me pidas "la operación entera" me da a entender que quieres copiar la solución tal cual y no preocuparte en hacerla tú.
Si la teoría la entiendes, deberías entender las explicaciones y si entiendes las explicaciones, deberías saber hacer tú mismo la operación.


EDIT: Además que me remito a tu propio mensaje del otro tema (ya sabrás de lo que te hablo)...
Citar
Estoy pidiendo ayuda porque NO SÉ HACERLO , no quiero que nadie me lo haga sólo quiero ayuda crack mastodonte
Aquí el tema (que no está muy lejos): https://foro.elhacker.net/bases_de_datos/ejercicio_algebra_relacional-t503904.0.html
Porque siendo dos cuentas nuevas, recién creadas y para el mismo problema... Las probabilidades de que ambas cuentas sean de la misma persona son muy altas. Visto que no tenía respuestas el otro tema pues habrás optado por hacer una cuenta nueva para "engañarnos" a todos, has añadido una consulta básica que no hace nada para que parezca que lo has intentado pero tu objetivo sigue siendo que te lo den hecho.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

#8
Cita de: YreX-DwX en 15 Abril 2020, 23:31 PM
Te he puesto la operación entera pero explicada por partes tanto con teoría como con ejemplos para que se vea lo que hace cada cosa.
Que me pidas "la operación entera" me da a entender que quieres copiar la solución tal cual y no preocuparte en hacerla tú.
Si la teoría la entiendes, deberías entender las explicaciones y si entiendes las explicaciones, deberías saber hacer tú mismo la operación.


EDIT: Además que me remito a tu propio mensaje del otro tema (ya sabrás de lo que te hablo)...Aquí el tema (que no está muy lejos): https://foro.elhacker.net/bases_de_datos/ejercicio_algebra_relacional-t503904.0.html
Porque siendo dos cuentas nuevas, recién creadas y para el mismo problema... Las probabilidades de que ambas cuentas sean de la misma persona son muy altas. Visto que no tenía respuestas el otro tema pues habrás optado por hacer una cuenta nueva para "engañarnos" a todos, has añadido una consulta básica que no hace nada para que parezca que lo has intentado pero tu objetivo sigue siendo que te lo den hecho.
Te estoy pidiendo la operación entera porque los ejemplos no los entiendo, y no la otra cuenta no soy yo.
Somo más gente en una clase con el mismo problema.

K-YreX

Cita de: rubcr en 15 Abril 2020, 23:40 PM
Te estoy pidiendo la operación entera porque los ejemplos no los entiendo, y no la otra cuenta no soy yo.
Somo más gente en una clase con el mismo problema.
Y si no entiendes una consulta hecha por partes, comentada y con ejemplos... Vas a entender mejor una consulta completa que ocupa dos líneas sin más?
Los ejemplos no los entiendes. Muy bien. Pues qué no entiendes de los ejemplos? Lo que es un producto cartesiano? Por qué utilizo la tabla Pedidos? Por qué igualo los códigos de una tabla con los de la otra?
Si eres más específico con tu duda, podré hacer otro intento en explicártelo. Por si no lo has notado estoy prefiriendo gastar más tiempo en hacerte una explicación completa que en darte la respuesta y que no la entiendas.

Y por estúpida que te parezca la pregunta que quieras hacer te dejo una frase para que te sirva de motivación: "Quien hace una pregunta es ignorante cinco minutos; quien no la hace será siempre ignorante."
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;