Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General »

Consulta con varias foraneas de una misma tabla

Estas en el tema de Consulta con varias foraneas de una misma tabla en el foro de Bases de Datos General en Foros del Web. Estimados, Tengo un problemilla... tengo este diagrama de base de datos: Reglas negocio: Un usuario pertenece y debe de pertenecer a sólo 3 empresas diferentes ...
  #1 (permalink)  
Antiguo 09/11/2010, 12:46
 
Fecha de Ingreso: mayo-2004
Ubicación: Santiago, Chile
Mensajes: 191
Antigüedad: 20 años
Puntos: 1
Consulta con varias foraneas de una misma tabla

Estimados,

Tengo un problemilla... tengo este diagrama de base de datos:



Reglas negocio:
Un usuario pertenece y debe de pertenecer a sólo 3 empresas diferentes entre si.

SQL:
Necesito traer en una consulta a todas las empresas a las que pertenece este usuario, pero no debo de mostrar el "ID_empresa", sino que su "razon_social".

Pregunta:
¿Cuál sería el SQL?

Con
Código:
    SELECT *
    FROM usuario
    INNER JOIN empresa ON usuario.ID_empresa = empresa.ID_empresa
    WHERE ID_usuario = XXX AND
    ORDER BY FECHA_CREACION DESC;
Me traigo sólo la primera razon social de la lista... gracias!!!
  #2 (permalink)  
Antiguo 09/11/2010, 12:59
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Consulta con varias foraneas de una misma tabla

Se trata de una relación N:M, por o que te está faltando una tabla intermedia que relacione los usuarios con las empresas, algo así como usuario_empresa(usuario_id, empresa_id).
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 09/11/2010, 15:18
 
Fecha de Ingreso: mayo-2004
Ubicación: Santiago, Chile
Mensajes: 191
Antigüedad: 20 años
Puntos: 1
Respuesta: Consulta con varias foraneas de una misma tabla

Pareciera una N:M, pero no lo es como tal, puesto que los usuarios deben estar en sólo 1 empresa (pero de cada tipo; dato1, dato2, dato3) y la empresa puede tener a varios usuarios.

Una N:M sería cuando varios usuarios (>1) pueden estar en varias empresas y varias empresas pueden contener a varios usuarios... este es un caso en donde un usuario esta sólo 1 una empresa pero debe tener de esos 3 tipos... se entiende?

Gracias!
  #4 (permalink)  
Antiguo 09/11/2010, 16:32
 
Fecha de Ingreso: octubre-2010
Ubicación: Monzon
Mensajes: 9
Antigüedad: 13 años, 6 meses
Puntos: 0
Respuesta: Consulta con varias foraneas de una misma tabla

No lo entiendo, pero si pones una tabla intermedia con un left join creo que lo tienes solucionado
Por otro lado si en la tabla del usuario tienes los campo empresa1, empresa2, empresa3, te diria que no es una buena forma de operar ya que la base de datos queda muerta ahí.
Creo que la mejor forma es meter un tabla intermedia y limitar con lenguaje, prcedimientos o lo que te sea más sencillo
  #5 (permalink)  
Antiguo 09/11/2010, 20:11
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Consulta con varias foraneas de una misma tabla

Cita:
Iniciado por Punchi Ver Mensaje
Pareciera una N:M, pero no lo es como tal, puesto que los usuarios deben estar en sólo 1 empresa (pero de cada tipo; dato1, dato2, dato3) y la empresa puede tener a varios usuarios.

Una N:M sería cuando varios usuarios (>1) pueden estar en varias empresas y varias empresas pueden contener a varios usuarios... este es un caso en donde un usuario esta sólo 1 una empresa pero debe tener de esos 3 tipos... se entiende?

Gracias!
Es más un tema de criterios de diseño.

El hecho de si necesitas o no una tercera tabla se basa en la forma de definir la relación entre las otras dos.

Si la relación es obligatoria, es decir si un mismo usuario debe estar vinculado a tres empresas y no puede estar vinculado a menos, es posible manejar eso con tres campos adicionales en la tabla usuarios, todos FK de empresa.

Pero si la relación es que puede estar vinculado hasta con tres empresas y como mínimo una, eso podría implicar una tercera tabla, por cuestiones de normalización. Hay que tener en cuenta que si la media de los registros no tiene los tres campos completos, se está desperdiciando espacio de almacenamiento (por pequeño que sea), y habitualmente en esos casos se recomienda separar esos conjuntos en una relación distinta.... que sería precisamente la N:M.

Además, es más simple manejar las relaciones de esa forma, ya que las consultas requieren dos JOIN y no tres como en tu propuesta..


En este punto la cosa tiene más que ver con el criterio del diseñador que con una metodología exclusiva.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Última edición por gnzsoloyo; 10/11/2010 a las 03:42
  #6 (permalink)  
Antiguo 10/11/2010, 06:24
 
Fecha de Ingreso: mayo-2004
Ubicación: Santiago, Chile
Mensajes: 191
Antigüedad: 20 años
Puntos: 1
Respuesta: Consulta con varias foraneas de una misma tabla

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Es más un tema de criterios de diseño.

El hecho de si necesitas o no una tercera tabla se basa en la forma de definir la relación entre las otras dos.

Si la relación es obligatoria, es decir si un mismo usuario debe estar vinculado a tres empresas y no puede estar vinculado a menos, es posible manejar eso con tres campos adicionales en la tabla usuarios, todos FK de empresa.

Pero si la relación es que puede estar vinculado hasta con tres empresas y como mínimo una, eso podría implicar una tercera tabla, por cuestiones de normalización. Hay que tener en cuenta que si la media de los registros no tiene los tres campos completos, se está desperdiciando espacio de almacenamiento (por pequeño que sea), y habitualmente en esos casos se recomienda separar esos conjuntos en una relación distinta.... que sería precisamente la N:M.

Además, es más simple manejar las relaciones de esa forma, ya que las consultas requieren dos JOIN y no tres como en tu propuesta..


En este punto la cosa tiene más que ver con el criterio del diseñador que con una metodología exclusiva.
Bien, creo que me entendiste mejor

Tal como tu dices, la relación es obligatoria y el usuario debe de pertenecer a no más y a no menos que a esas 3 empresas, siempre y en todos los casos, ya que cada empresa (diferente entre si) está relacionado a un tipo que ese usuario debe de tener.

Ya habiéndome entendido, puedo realizar la consulta que quiero con 2 select, pero no con 1... ¿es posible hacerlo con uno? "mostrar las (3) empresas a las que pertenece este usuario, pero no debe de mostrar el "ID_empresa", sino que su "razon_social""

  #7 (permalink)  
Antiguo 10/11/2010, 06:55
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Consulta con varias foraneas de una misma tabla

Cita:
Ya habiéndome entendido, puedo realizar la consulta que quiero con 2 select, pero no con 1... ¿es posible hacerlo con uno? "mostrar las (3) empresas a las que pertenece este usuario, pero no debe de mostrar el "ID_empresa", sino que su "razon_social""
No estoy hablando de SELECTs sino de JOINs.
Es perfectamente posible hacerlo en una sola consulta, aunque hay que considerar los NULL si vas a usar sólo dos tablas.
La idea es:
Código MySQL:
Ver original
  1.   usuario U
  2.   empresa E1 ON u.ID_empresa = E1.ID_empresa1
  3.   empresa E2 ON u.ID_empresa = E2.ID_empresa2
  4.   empresa E3 ON u.ID_empresa = E3.ID_empresa3
  5.   ID_usuario = XXX
  6.   OR U.ID_empresa1 IS NULL
  7.   OR U.ID_empresa2 IS NULL
  8.   OR U.ID_empresa1 IS NULL
  9. ORDER BY FECHA_CREACION DESC;

Debería funcionar, pero completa los campos del SELECT para obtener lo que tu necesitas. No conozco la estructura de tus tablas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 24/11/2010, 15:14
 
Fecha de Ingreso: mayo-2004
Ubicación: Santiago, Chile
Mensajes: 191
Antigüedad: 20 años
Puntos: 1
Respuesta: Consulta con varias foraneas de una misma tabla

Gracias gnzsoloyo,

Disculpa por no seguir seguido con el tema, empecé a ver otras cosas y he vuelto con este problema. En la base de datos física cada "ID_empresa" es reemplazado por el tipo de empresa, la base de datos final queda:



Código:
/*==============================================================*/
/* Table: EMPRESA                                               */
/*==============================================================*/
create table EMPRESA
(
   ID_EMPRESA           varchar(11) not null,
   RAZON_SOCIAL         varchar(512),
   primary key (ID_EMPRESA)
);

/*==============================================================*/
/* Table: USUARIO                                               */
/*==============================================================*/
create table USUARIO
(
   ID_USUARIO           int not null auto_increment,
   ID_EMPRESA1          varchar(11),
   ID_EMPRESA2          varchar(11),
   ID_EMPRESA3          varchar(11),
   NOMBRE               varchar(1024),
   primary key (ID_USUARIO)
);

alter table USUARIO add constraint FK_DATO1 foreign key (ID_EMPRESA1)
      references EMPRESA (ID_EMPRESA) on delete restrict on update restrict;

alter table USUARIO add constraint FK_DATO2 foreign key (ID_EMPRESA2)
      references EMPRESA (ID_EMPRESA) on delete restrict on update restrict;

alter table USUARIO add constraint FK_DATO3 foreign key (ID_EMPRESA3)
      references EMPRESA (ID_EMPRESA) on delete restrict on update restrict;
Creando algunos datos...

Código:
INSERT INTO `empresa` (`ID_EMPRESA`, `RAZON_SOCIAL`) VALUES
('1111111111', 'empresa numero uno'),
('2222222222', 'empresa numero dos'),
('3333333333', 'empresa numero tres'),
('444444444', 'empresa numero cuatro');

INSERT INTO `usuario` (`ID_USUARIO`, `ID_EMPRESA1`, `ID_EMPRESA2`, `ID_EMPRESA3`, `NOMBRE`) VALUES
(123, '1111111111', '2222222222', '3333333333', 'usuario unodostres'),
(456, '444444444', '2222222222', '1111111111', 'otrousuario');
Acomodando el código, quedaría:

Código:
SELECT *
FROM
  usuario U
  LEFT JOIN
  empresa E1 ON u.ID_EMPRESA1 = E1.ID_EMPRESA
  LEFT JOIN
  empresa E2 ON u.ID_EMPRESA2 = E2.ID_EMPRESA
  LEFT JOIN
  empresa E3 ON u.ID_EMPRESA3 = E3.ID_EMPRESA;
El que efectivamente arroja la RAZON_SOCIAL

Acomodamos un poco...

Código:
SELECT E1.RAZON_SOCIAL as DATO1, E2.RAZON_SOCIAL as DATO2
FROM
  usuario U
  LEFT JOIN
  empresa E1 ON u.ID_EMPRESA1 = E1.ID_EMPRESA
  LEFT JOIN
  empresa E2 ON u.ID_EMPRESA2 = E2.ID_EMPRESA
  LEFT JOIN
  empresa E3 ON u.ID_EMPRESA3 = E3.ID_EMPRESA;
Y listo!!!

Gracias! Les dejo la info a los demas, por si les sirve.

Etiquetas: tablas, foreignkey
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:48.