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

consulta atragantada

Estas en el tema de consulta atragantada en el foro de Bases de Datos General en Foros del Web. Hola amig@s. Tengo una consulta que, probablemente no sea muy difícil, pero a mí se me ha atragantado totalmente. Vereis, tengo que combinar 3 tablas, ...
  #1 (permalink)  
Antiguo 09/05/2011, 03:29
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
consulta atragantada

Hola amig@s.
Tengo una consulta que, probablemente no sea muy difícil, pero a mí se me ha atragantado totalmente.

Vereis, tengo que combinar 3 tablas, una de servicios, otra de usuarios y otra de empresas.

Los servicios tienen, entre otros campos, uno para el usuario, que puede ser un dni o un cif.

Yo en la consulta le hago un ifnull(nombre_usuario, ''), ifnull(nombre_empresa, '').

Luego me lío con los right, left, inner join de la tabla servicios con las tablas usuarios y empresas.

Qué debería hacer para que me salieran los servicios, se refieran a empresas o a usuarios??

Mil gracias.
  #2 (permalink)  
Antiguo 09/05/2011, 03:37
 
Fecha de Ingreso: marzo-2007
Mensajes: 127
Antigüedad: 17 años, 1 mes
Puntos: 2
Respuesta: consulta atragantada

Hola aniMAYtions:

Yo no soy experto en SQL, por lo que no creo que te pueda ayudar, pero me imagino que la gente te podrá ayudar mejor si indicas la estructura de tus tablas y la sentencia SQL que estás usando actualmente para que te la puedan corregir.

Saludos.
  #3 (permalink)  
Antiguo 09/05/2011, 03:44
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: consulta atragantada

Gracias pumi, pero creo que con eso sabrán a qué me refiero, aunque si alguien puede ayudarme y con esos datos no tiene suficiente yo le escribo la consulta completa.
Lo que pasa es que es muy larga, muy enrevesada y se refiere a muchas otras tablas...
Un saludo
  #4 (permalink)  
Antiguo 09/05/2011, 07:08
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, 4 meses
Puntos: 2658
Respuesta: consulta atragantada

Lo que estás diciendo es insuficiente ni para empezar a imaginar.
Como el problema es muy puntual (es tu caso, en base a tus tablas), es absolutamente necesario saber cómo están estructuradas esas tablas; de ese modo podemos ver las relaciones sin tener que estar preguntándote todos los detalles.
La consulta es absolutamente necesaria, porque muchos problemas se dan por el uso inadecuado de los JOINs, y si no vemos qué estas haciendo, mal podemos decirte qué tienes que corregir. Además, en ocasiones el problema no está en la consulta en forma general, sino en la lógica aplicada a las condiciones (suele pasar que lo que busca pedir no es lo que efectivamente se está pidiendo).

Postea qué DBMS usas, la estructura de tablas (el CREATE TABLE...), y la consulta usada.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 09/05/2011, 08:28
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: consulta atragantada

Gracias por el apunte gnzsoloyo. Intentaba ahorrarme escribir código...

Veamos, en mi consulta deben aparecer muchos nombres que se encuentran en distintas tablas a la de servicios.
Primero pongo la consulta y luego paso a explicar.
Código MySQL:
Ver original
  1. Select id_servicio, ifnull(id_codserv, ''), ifnull(nombre_usuario, ''), nombre, ifnull(nombre_institucion, ''), date_format(finicio_servicio, '%d/%m/%Y'), nombre_estado, date_format(finicio_servicio, '%H:%i'), v.id_estado, v.id_tiposervicio, ifnull(nombre_empresa, '')
  2. from servicios v left join instituciones i on v.id_institucion = i.id_institucion
  3. inner join usuarios u on v.usuario = u.username
  4. inner join usu_plataforma up on v.trabajador = up.username
  5. left join estado e on v.id_estado = e.id_estado
  6. left join empresas emp on v.usuario = emp.cif
  7. where v.usuario != '0' "

Vale, a mi lo que me interesa es la tabla servicios. Para obtener el nombre del usuario tengo que enlazarla a la tabla usuarios por el dni y para obtener el nombre de la empresa me dirijo a la tabla empresas enlazandola con el cif. Hay que destacar que el usuario del servicio puede ser tanto un dni como un cif(o sea, tanto una persona como una empresa). Por lo tanto en servicios no hay 2 campos, sólo 1 y debería poder identificar en qué tabla se encuentra el nombre asociado al usuario.
Nombre lo obtiene de la tabla usu_plataforma y es el nombre del trabajador que se enlaza a servicios por el dni del trabajador(este sí es un campo aparte).
El nombre de la institución pertenece a la tabla instituciones. Puede ser nulo si no se ingresa ese dato en el servicio(no es olbigatorio).
Los estados aparecen reflejados en la tabla estado y se relacionan con servicios por el id.
El tipo de servicio igual, otra tabla con los tipos que se relaciona con el servicio por el id.

Luego van los filtros, pero eso es lo de menos. Si la consulta no se filtra queda así.
La cosa está en que olvidé la teoría de los left, right e inner join y no encuentro hueco para repasarla con tanto trabajo...

Espero que ya no quepa duda alguna.

Muchas gracias y saludos!!
  #6 (permalink)  
Antiguo 09/05/2011, 09:04
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, 4 meses
Puntos: 2658
Respuesta: consulta atragantada

Cita:
Vale, a mi lo que me interesa es la tabla servicios. Para obtener el nombre del usuario tengo que enlazarla a la tabla usuarios por el dni y para obtener el nombre de la empresa me dirijo a la tabla empresas enlazandola con el cif. Hay que destacar que el usuario del servicio puede ser tanto un dni como un cif(o sea, tanto una persona como una empresa). Por lo tanto en servicios no hay 2 campos, sólo 1 y debería poder identificar en qué tabla se encuentra el nombre asociado al usuario.
Bueno, por empezar tienes problemas de análisis y diseño. De análisis, porque estás planteando un sistema algo conflictivo, cuando quieres relacionar un mismo campos de una tabla con dos campos de tablas distitas, cuyo dominio es completamente diferente... En Análisis de Sistemas eso te hubiese reprobado cualquier examen. La explicación de por qué está mal es demasiado larga para postearla ahora.
Vamos al problema de la consulta.

La consulta que plantea pretende obtener datos de "servicios", brindados a usuarios que pueden ser empresas o personas. Pero lo que pides es que si o si correspondan a usuarios (el INNER JOIN a Usuarios), y sólo te devuelva datos de las empresas si la clave es igual a la del usuario.
¿Se percibe la contradicción?: No estás pidiendo que devuelva un u otro. Estás pidiendo sólo la de los usuarios, y relacionando a los usuarios con las empresas. Si el valor es uno u otro, sólo podría darte empresas si su ID es igual al de un usuario ( más allá de si el usuario pertenece o no a esa empresa, cosa que no está clara).
La vinculación con la tabla usu_plataforma también es obligatoria, de modo que sólo devolverá registros si el servicio tiene algún usuario y al mismo tiempo algún trabajador vinculado. De lo contrario no devolverá nada.

Por la descripción general de lo que estás vinculando tengo la impresión de que el modelado general de entidades y relaciones no está bien hecho, y si partes de un esquema mal planteado te vas a encontrar con problemas en las consultas todo el tiempo.

Por eso decía que era muy importante que postearas las estructuras de las tablas. La consulta parece mostrar inconsistencia en las relaciones que conspiran contra la misma, y eso sólo se ve en la definición del CREATE TABLE de las tablas involucradas.

PD. Si este post te parece largo, deberías ver otros posts que he escrito.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 09/05/2011, 09:20
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: consulta atragantada

Gracias de nuevo por tu respuesta gnzsoloyo.

Te explico por qué creé esta estructura. Los usuarios tienen campos obligatorios como son fecha nacimiento, sexo, direccion, poblacion, email, telefono... Las empresas solo tienen cif y nombre de empresa.
Yo aprendí que las tablas con muchos campos nulos son inconsitentes. Por eso pensé en esta distribución.
Aunque te doy la razón en todo lo que expones, las prisas a veces nos juegan malas pasadas y no esperaba tener que enfrentarme a una consulta de esta embergadura.

Solución?
Si no quiero tener muchos nulos o campos vacíos(pues la mayoría no pueden estar a null y tendría que dar un valor por defecto) puedo crear una tabla intermedia que me diga el dni o cif y el tipo de usuario(si 1 usuario, si 2 empresa, por ejemplo) y buscar en una tabla u otra la información. Pero estamos en las misma, ahora no se me ocurre enlazar la consulta a esta nueva tabla para que me de la información que necesito.
Y la verdad es que tampoco tengo demasiado tiempo ni para pensar ni hacer un repaso de los joins, sólo programar...

Gracias una vez más y saludos.
  #8 (permalink)  
Antiguo 10/05/2011, 00:35
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: consulta atragantada

Bueno, sólo decir que al final he tomado la opción de meter las empresas en la tabla usuarios, con fecha de nacimiento = '0000:00:00'(es un campo no nulo) e id_sexo = 2(0 hombre, 1 mujer y 2 empresa) y por ese campo los distingo.
Así todo es más rápido, que es lo que me piden.

Un saludo y hasta la próxima.

Etiquetas: mysql, bases-de-datos
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 04:03.