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

Subsonculta a la misma tabla para generar vista.

Estas en el tema de Subsonculta a la misma tabla para generar vista. en el foro de Mysql en Foros del Web. Hola estimados!!! Tengo un inconveniente y no logro resolverlo, entiendo el tema de subconsultas, pero no me arroja resultados cuando la realizo a la misma ...
  #1 (permalink)  
Antiguo 30/11/2015, 08:29
Avatar de NLeone  
Fecha de Ingreso: junio-2012
Ubicación: Buenos Aires.
Mensajes: 22
Antigüedad: 11 años, 10 meses
Puntos: 0
Subsonculta a la misma tabla para generar vista.

Hola estimados!!!

Tengo un inconveniente y no logro resolverlo, entiendo el tema de subconsultas, pero no me arroja resultados cuando la realizo a la misma tabla, he visto ejemplos pero no es lo que busco, con inner join , etc.

El tema es que tengo una tabla padronBeneficiarios con campos relacionados a otras tablas como ser provincias, codigoEstado, codParentesco, etc. Entonces busco mostrar en una vista los campos con los datos bien representados, por ejemplo si el código de parentesco es 1, quiero que en vez de mostrar el número 1 al usuario le muestre que es 'titular'. Y así con todo.

La tabla padronBeneficiarios me la provee un organismo del Estado por eso no puedo modificar su estructura, y las tablas auxiliares son las que me proveen los datos para realizar las combinaciones.

Dejo la query como más o menos la tengo armada:

Código MYSQL:
Ver original
  1. SELECT a.id, a.codObraSocial, a.cuitEmpleador,
  2. (SELECT k.apenomDetail FROM detailDdjjPadron k WHERE k.cuitDetail = a.cuitEmpleador) as 'razonSocial',
  3. a.cuilTitular,
  4. (SELECT b.descripcion FROM codParentescoSSS b WHERE b.id = a.codParentesco) as 'parentesco',
  5. a.cuilCuil,
  6. (SELECT c.tipoDocumento FROM tipoDocSSS c WHERE c.id = a.tipoDocumento) as 'tipoDocumento',
  7. a.numeroDocumento, a.apellidoNombre, a.sexo,
  8. (SELECT d.descripcion FROM estadoCivilSSS d WHERE d.id = a.estadoCivil) as 'estadoCivil',
  9. a.fechaNacimiento,
  10. (SELECT e.descripcion FROM nacionalidadSSS e WHERE e.id = a.nacionalidad) as 'nacionalidad',
  11. a.calle, a.numeroPuerta, a.piso, a.departamento, a.localidad, a.codigoPostal,
  12. (SELECT f.nombre FROM provinciasSSS f WHERE f.id = a.codProvincia) as 'provincia',
  13. (SELECT g.descripcion FROM tipoDomicilioSSS g WHERE g.id = a.tipoDomicilio) as 'tipoDomicilio',
  14. a.telefono, a.situacionRevista,
  15. (SELECT h.descripcion FROM incapacidadSSS h WHERE h.id = a.incapacidad) as 'incapacidad',
  16. (SELECT i.descripcion FROM tipoBenefSSS i WHERE i.id = a.tipoBeneficiario) as 'tipoBeneficiario',
  17. a.fechaAltaOS, a.fechaCierrePres, a.codMovimiento,
  18. (SELECT j.descripcion FROM estado j WHERE j.idEstado = a.idEstado) as 'estado',
  19. a.usuarioAlta, a.fechaAlta, a.usuarioModificacion, a.fechaModificacion FROM padronBeneficiarios a;

Y eso me devuelve bien los registros, pero lo que me falta es agregar algo como esto:
Código MySQL:
Ver original
  1. (SELECT q.apellidoNombre FROM padronBeneficiarios q WHERE q.cuilTitular = a.cuilCuil) as 'titular'

Como para obtener el apellido y nombre que se encuentra en la misma tabla, que sea igual al cuilCuil del registro que esté comparando. Para mostrar al lado el nombre del titular de la obra social.

Bueno espero que más o menos se haya entendido mi problemática, y obviamente no logro darme cuenta cómo solucionarlo, por eso recurro a ustedes.

Muchas gracias y cualquier respuesta será bienvenida, saludos!!

Última edición por gnzsoloyo; 30/11/2015 a las 10:54
  #2 (permalink)  
Antiguo 30/11/2015, 09:28
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subsonculta a la misma tabla para generar vista.

Te regresa los resultados que esperas pero esa consulta no esta nada bien realizada, lo mejor seria que hicieras algo como esto:

Código SQL:
Ver original
  1. SELECT * FROM tabla AS a
  2. INNER JOIN tablab ON (a.id=b.id)

en tu caso:

Código MySQL:
Ver original
  1. SELECT a.id, a.codObraSocial, a.cuitEmpleador,
  2. k.apenomDetail  as 'razonSocial',
  3. a.cuilTitular,
  4. a.usuarioAlta, a.fechaAlta, a.usuarioModificacion, a.fechaModificacion FROM padronBeneficiarios a
  5. inner join detailddjjpadron as K on (k.ciutdetail=a.cuitempleador)

y asi para las demas tablas implicadas en el query :)

y si ocupas hacer una referencia cruzada a la tabla podrias hacer algo como esto:

Código SQL:
Ver original
  1. SELECT * FROM tabla AS a
  2. INNER JOIN tabla AS b ON (a.id=b.id2)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 30/11/2015, 09:56
Avatar de NLeone  
Fecha de Ingreso: junio-2012
Ubicación: Buenos Aires.
Mensajes: 22
Antigüedad: 11 años, 10 meses
Puntos: 0
Respuesta: Subsonculta a la misma tabla para generar vista.

Estimado Libras muchas gracias por tu tiempo!

Entiendo lo que dices, a que no esta bien realizada te refieres a muchas subconsultas dentro de la consulta? eso es una mala práctica?

Soy novato en esto.

Intentaré realizar lo que dices y cuento el resultado, el hecho es que los JOINS son más efectivos?

No quiero que demore mucho la consulta, tengo alrededor de 13 mil registros para recuperar.

Bueno, muchas gracias, en unas horas lo pruebo y vuelvo a mostrar resultados.

Saludos!
  #4 (permalink)  
Antiguo 30/11/2015, 10:52
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Subsonculta a la misma tabla para generar vista.

asi es muchas subconsultas te puede pegar en el performance y usar joins es mucho mas efectivo ;)
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #5 (permalink)  
Antiguo 30/11/2015, 11:13
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: Subsonculta a la misma tabla para generar vista.

Probemos limpiando un poco el código:
Código MySQL:
Ver original
  1. SELECT a.id,
  2.        a.codObraSocial,
  3.        a.cuitEmpleador,
  4.        k.apenomDetail razonSocial,
  5.        a.cuilTitular,
  6.        b.descripcion parentesco,
  7.        a.cuilCuil,
  8.        c.tipoDocumento tipoDocumento,
  9.        a.numeroDocumento,
  10.        a.apellidoNombre,
  11.        a.sexo,
  12.        d.descripcion estadoCivil,
  13.        a.fechaNacimiento,
  14.        e.descripcion nacionalidad,
  15.        a.calle,
  16.        a.numeroPuerta,
  17.        a.piso,
  18.        a.departamento,
  19.        a.localidad, a.codigoPostal,
  20.        f.nombre provincia,
  21.        g.descripcion tipoDomicilio,
  22.        a.telefono,
  23.        a.situacionRevista,
  24.        h.descripcion incapacidad,
  25.        i.descripcion tipoBeneficiario,
  26.        a.fechaAltaOS,
  27.        a.fechaCierrePres,
  28.        a.codMovimiento,
  29.        j.descripcion estado,
  30.        a.usuarioAlta,
  31.        a.fechaAlta,
  32.        a.usuarioModificacion,
  33.        a.fechaModificacion
  34. FROM padronBeneficiarios a
  35.     INNER JOIN detailDdjjPadron k ON k.cuitDetail = a.cuitEmpleador
  36.     INNER JOIN codParentescoSSS b ON  b.id = a.codParentesco
  37.     INNER JOIN tipoDocSSS c ON c.id = a.tipoDocumento
  38.     INNER JOIN estadoCivilSSS d ON  d.id = a.estadoCivil
  39.     INNER JOIN nacionalidadSSS e ON  e.id = a.nacionalidad
  40.     INNER JOIN provinciasSSS f ON f.id = a.codProvincia
  41.     INNER JOIN tipoDomicilioSSS g ON  g.id = a.tipoDomicilio
  42.     INNER JOIN incapacidadSSS h ON h.id = a.incapacidad
  43.     INNER JOIN tipoBenefSSS i ON  i.id = a.tipoBeneficiario
  44.     INNER JOIN estado j ON j.idEstado = a.idEstado;

Luego, veamos si algunas de esas condiciones son opcionales, y en ese caso en el FROM su invocación se reemplaza de INNER a LEFT.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 30/11/2015, 11:36
Avatar de NLeone  
Fecha de Ingreso: junio-2012
Ubicación: Buenos Aires.
Mensajes: 22
Antigüedad: 11 años, 10 meses
Puntos: 0
Respuesta: Subsonculta a la misma tabla para generar vista.

Muchas gracias una vez más Libras!

Por otro lado gnzsoloyo, también agradezco mucho tu tiempo.

He probado la consulta tal como me la transcribes y resulta bárbaro, solo falta algunos retoques como por ejemplo ORDER BY id, pero son detalles.

No he entendido la parte final en la que me dices "Luego, veamos si algunas de esas condiciones son opcionales, y en ese caso en el FROM su invocación se reemplaza de INNER a LEFT."

Las condiciones son restrictivas osea no son opcionales porque sí o sí deben cumplir esas condiciones.

Pero no logro entenderte a qué te refieres, hasta donde sé LEFT o RIGHT trae todo el conjunto de datos de la tabla de la derecha o de la izquierda, pero en mi caso solo quiero el campo el al cual hago referencia en cada una de las opciones está bien?

Por otro lado pregunto ya que estoy en el baile, hay forma de optimizar más aún esta query? porque esto se muestra en un dataGrid, que mediante ajax llama al archivo PHP que ejecuta dicha consulta, en mysql workbench demora 2,659 sec / 4,640 sec, pero al ejecutarlo en la aplicación demora unos instantes más.....

Muchas gracias nuevamente.
  #7 (permalink)  
Antiguo 30/11/2015, 11:58
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: Subsonculta a la misma tabla para generar vista.

Cita:
Pero no logro entenderte a qué te refieres, hasta donde sé LEFT o RIGHT trae todo el conjunto de datos de la tabla de la derecha o de la izquierda, pero en mi caso solo quiero el campo el al cual hago referencia en cada una de las opciones está bien?
Es simplemente que estaba indicando que si todas las condiciones son obligatorias, se usa INNER JOIN, pero que si alguna de ellas es opcional, es decir que un Beneficiario dado puede no tener registros en alguna tabla, pero quieres que de todos modos salga en el resultado, hay que usar LEFT JOIN en el punto adecuado, analizando con cuidado la cadena de dependencias para asegurar que no haya errores de resultados en los datos.

Son cosas que se aprende con la práctica.
__________________
¿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 30/11/2015, 12:00
Avatar de NLeone  
Fecha de Ingreso: junio-2012
Ubicación: Buenos Aires.
Mensajes: 22
Antigüedad: 11 años, 10 meses
Puntos: 0
Respuesta: Subsonculta a la misma tabla para generar vista.

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Es simplemente que estaba indicando que si todas las condiciones son obligatorias, se usa INNER JOIN, pero que si alguna de ellas es opcional, es decir que un Beneficiario dado puede no tener registros en alguna tabla, pero quieres que de todos modos salga en el resultado, hay que usar LEFT JOIN en el punto adecuado, analizando con cuidado la cadena de dependencias para asegurar que no haya errores de resultados en los datos.

Son cosas que se aprende con la práctica.
Ahhhhh, ahora he entendido, entonces si deberé utilizar en algunos casos el LEFT JOIN....

Me han ayudado mucho y rápidamente! Solo me falta ver si se puede agilizar el tiempo de ejecución de la query pero ya iré probando.

Muchas gracias nuevamente ! Saludos!

Etiquetas: campo, fecha, join, select, tabla
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 11:02.