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

Al cruzar tablas necesito que arroje una vez el campo en común

Estas en el tema de Al cruzar tablas necesito que arroje una vez el campo en común en el foro de Bases de Datos General en Foros del Web. Hola a todos, haber si alguien sabe como ayudarme. Tengo dos tablas una de temas y la otra de enlaces relacionados al tema Cruzo las ...
  #1 (permalink)  
Antiguo 13/10/2010, 12:57
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Al cruzar tablas necesito que arroje una vez el campo en común

Hola a todos, haber si alguien sabe como ayudarme.
Tengo dos tablas una de temas y la otra de enlaces relacionados al tema

Cruzo las dos tablas, he probado de miles de formas pero me arroja :
todos los enlaces pero por cada enlace el tema se repite.

tabla tema:
id | nombre_tema |


tabla sitios_web_por_tema
id | id_tema | sitio_web | enlace_web | idioma

Lo que necesito es que me arroje

tema1
enlace 1
enlace2
enlace3

tema 2
enlace 4
enlace 5
enlace6

En este momento lo que me arroja es
tema1
enlace1
tema1
enlace2
tema1
enlace3

tema2
enlace4
tema2
enlace5
tema2
enlace6

tengo escrito lo siguiente:

Código HTML:
select * from sitios_web_por_tema, temas where id_idioma='1' and id_concepto='5' and sitios_web_por_tema.id_tema=temas.id
Parece una chorrada pero me lleva de cabeza ya demasiado.
He revisado los enlaces de tutoriales y en ninguna parte he encontrado el detalle de que no se repita un campo como aquí.
Por favor, necesito ayuda, lo agradecería mucho.

Un saludo a todos
  #2 (permalink)  
Antiguo 13/10/2010, 13:17
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: Al cruzar tablas necesito que arroje una vez el campo en común

Habría que probar:
Código SQL:
Ver original
  1. SELECT *
  2. FROM sitios_web_por_tema W INNER JOIN temas T ON W.id_tema = T.id
  3. WHERE id_idioma='1' AND id_concepto='5'
__________________
¿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 13/10/2010, 15:10
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Buenas Tardes modeff, creo que falto alguna información con respecto a la estructura de tus tablas y tus datos, pues no sé de donde sacas el campo id_concepto que aparece en tu where. Pero vamos a ver si más o menos entendí lo que quieres.

Supongamos que tu tabla temas tiene más o menos los siguientes datos:

Código:
id|nombre_tema
----------------
1|Tema 1
2|Tema 2
3|Tema 3
Supongamos que tu tabla sitios_web_por_tema tiene más o menos los siguientes datos:

Código:
id|id_tema|sitio_web|enlace_web|idioma
---------------------------
1|1|sitio 1|enlace 1|5
2|1|sitio 2|enlace 2|5
3|1|sitio 3|enlace 3|5
4|2|sitio 4|enlace 4|5
5|2|sitio 5|enlace 5|5
6|2|sitio 6|enlace 6|5
Puedes probar con esto a ver si te funciona:

Código SQL:
Ver original
  1. SELECT 1 AS nivel, id, T1.nombre_tema AS descripcion FROM temas T1
  2. UNION
  3. SELECT 2 AS nivel, W.id_tema AS id, W.enlace_web AS descripcion
  4. FROM sitios_web_por_tema W INNER JOIN temas T2 ON W.id_tema = T2.id
  5. WHERE idioma = '5'
  6. --Agregar la condición para id_concepto
  7. ORDER BY id, nivel, descripcion
Esta consulta te regresa lo siguiente:

Código:
nivel|id|descripcion
------------------------
1|1|Tema 1
2|1|Enlace 1
2|1|Enlace 2
2|1|Enlace 3
1|2|Tema 2
2|2|Enlace 4
2|2|Enlace 5
2|2|Enlace 6
1|3|Tema 3
Saludos
Leo.
  #4 (permalink)  
Antiguo 14/10/2010, 02:45
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Hey muchas gracias por la ayuda
gnzsoloyo y leonardo_josue

Cita:
Buenas Tardes modeff, creo que falto alguna información con respecto a la estructura de tus tablas y tus datos, pues no sé de donde sacas el campo id_concepto que aparece en tu where. Pero vamos a ver si más o menos entendí lo que quieres.
Ese campo existe en la tabla, traté de resumir el asunto, pero no falta más.

Con respecto a lo que me proponen tengo algunas preguntas
primero:
gnzsoloyo:
Cita:
1.
SELECT *
2.
FROM sitios_web_por_tema W INNER JOIN temas T ON W.id_tema = T.id
3.
WHERE id_idioma='1' AND id_concepto='5'
¿que significa la w delante de INNER JOIN y la T detras del ON? pues me ha confundido un poco.

leonardo_josue

Cita:
1.
SELECT 1 AS nivel, id, T1.nombre_tema AS descripcion FROM temas T1
2.
UNION
3.
SELECT 2 AS nivel, W.id_tema AS id, W.enlace_web AS descripcion
4.
FROM sitios_web_por_tema W INNER JOIN temas T2 ON W.id_tema = T2.id
5.
WHERE idioma = '5'
6.
--Agregar la condición para id_concepto
7.
ORDER BY id, nivel, descripcion
Aquí también pones W delante de INNER JOIN y además usas 1, nivel, t1
.. Me imagino que con este código creo una tabla temporal con campo nivel, pero necesito esos detallitos que no logro saber a que corresponde .

Quiero probar con los dos ejemplos haber como se comportan.

Por favor ¿me podrían aclarar mis dudas? nuevamente muchas gracias por su ayuda chicos.
  #5 (permalink)  
Antiguo 14/10/2010, 05:01
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: Al cruzar tablas necesito que arroje una vez el campo en común

Es un alias, es decir, una indicación de que el nombre precedente será cambiado en las invocaciones subsiguientes o precedentes por ese.

Los alias se usan para evitar tener que escribir los nombres completos de tablas o bases en algunos momentos, o bien para cambiarles los nombres a las columnas. Cuando se usan en el FROM suplantan el nombre de la tabla y cuando se usan en el SELECT los de las columnas.

Tips:

1. Antiguamente, y en algunos DBMS muy viejos se suele usar la cláusula AS para indicar el nombre del alias. Desde hace años eso no forma parte del estándar ANSI-SQL, por lo que es opcional. Yo no lo pongo porque para mí sólo ensucia el código sin cumplir ninguna función.

2. No se puede usar en el WHERE los alias del SELECT para referirse a una columna. Los únicos alias que pueden operar en el WHERE son los de las tablas.

3. Se pueden usar en las cláusulas GROUP BY, ORDER BY y HAVING. Si hay restricciones sobre esto, dependen del DBMS.

Consejo final: Lee un poco más sobre SQL, porque estas son cosas que salen en los manuales MUY básico, así como el JOIN y todas sus formas. Te beneficiará mucho.
__________________
¿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; 14/10/2010 a las 05:13
  #6 (permalink)  
Antiguo 14/10/2010, 05:28
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Hola gnzsoloyo,
me he bajado varios manuales, estoy estudiando más en profundidad y tus explicaciones me han servido mucho. ¿que manual me recomiendas?
quizás tienes un más completo que los que tengo

He probado tu código y me sigue arrojando la repetición del tema.

Además he probado el codigo de Leo (leonardo_josue) y me arroja el icono que acompaña al tema pero todo vacío sin los enlaces. ¿cómo llamo a los campos virtuales de la tabla temporal que se crea en el código de Leo? quizás ahí está mi problema.

Muchas gracias nuevamente por la ayuda

Modeff
  #7 (permalink)  
Antiguo 14/10/2010, 05:50
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: Al cruzar tablas necesito que arroje una vez el campo en común

Cita:
me he bajado varios manuales, estoy estudiando más en profundidad y tus explicaciones me han servido mucho. ¿que manual me recomiendas?
quizás tienes un más completo que los que tengo
Más que un manual, te recomendaría que hicieras un curso sobre bases de datos, porque ningún manual puede en algunos momentos suplantar lo que te aporta un instructor, no sólo por experiencia, sino por la claridad de comprender algunos conceptos que son esencialmente abstractos, como es el caso del análisis y diseño de bases de datos.
Cita:
He probado tu código y me sigue arrojando la repetición del tema.
El uso de INNER JOIN sólo puede darte repeticiones de registro en la primera tabla si existen al menos dos registros referidos al mismo sitio. Que se repitan datos de la segunda tabla es perfectamente lógico, porque dos sitios diferentes pueden contener el mismo tema.
Si lo que quieres es que sólo te devuelva un sitio por tema, lo que se debe hacer es un GROUP BY por el tema:

Código SQL:
Ver original
  1. SELECT T.*, W.*
  2. FROM sitios_web_por_tema W INNER JOIN temas T ON W.id_tema = T.id
  3. WHERE id_idioma='1' AND id_concepto='5'
  4. GROUP BY T.id

En cambio, si lo que quieres es ordenarlos de una forma determinada, sería:

Código SQL:
Ver original
  1. SELECT T.*, W.*
  2. FROM sitios_web_por_tema W INNER JOIN temas T ON W.id_tema = T.id
  3. WHERE id_idioma='1' AND id_concepto='5'
  4. ORDER BY T.id, W.id

Infortunadamente lo que hace un DBMS es devolverte una tabla, y cada dato diferente está representado por una columna diferente, por lo que hacer algo así:
Cita:
tema1
enlace 1
enlace2
enlace3

tema 2
enlace 4
enlace 5
enlace6
Es algo que debes resolver en la aplicación, no en el DBMS. SQL Sólo puede construir esto:
Cita:
tema1 enlace 1
tema1 enlace2
tema1 enlace3
tema2 enlace 4
tema2 enlace 5
tema2 enlace6
Respecto al ejemplo propuesto por leonardo_josué, lamento advertirte que lo que te traerá será esto:
Cita:
nivel|id|descripcion
------------------------
1|1|Tema 1
1|2|Tema 2
1|3|Tema 3
2|1|Enlace 1
2|1|Enlace 2
2|1|Enlace 3
2|2|Enlace 4
2|2|Enlace 5
2|2|Enlace 6
porque en un UNION, el último ORDER BY afecta la totalidad de la tabla devuelta y no una parte de ella, por lo que ordenará las dos primeras columnas de todos los registros primero.
Además, como propuesta no considera que existan más de tres temas. Ese modelo debería iterarse tantas veces como temas haya, por lo que no puedes crear una única sentencia que lo haga.
__________________
¿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; 14/10/2010 a las 06:03
  #8 (permalink)  
Antiguo 14/10/2010, 06:25
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Hola Chicos:

gnzsoloyo:
He seguido probando y no me sirve para lo que necesito. Muchas gracias de todas maneras.

Usé el código de Leo y funciona tal como esperaba, sólo por un detalle que veré ahora como solucionarlo que me manda todos los temas, no solo los que tienen enlaces, pero ya es un tremendo avance y agradezco mucho la ayuda de ustedes dos.

Un abrazo muy grande y si se les ocurre alguna solución siempre es bienvenida, aunque ya tengo casi solucionado el problema.

Modeff
  #9 (permalink)  
Antiguo 14/10/2010, 08:46
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Buenas tardes modeff, espero que ya gnzsoloyo te haya resuelto las dudas con respecto a los alias, pero si continuas con problemas para entender la consulta que puse me lo comentas para tratar de explicarla.

Por lo que comentas en tu último post al parecer sí te funcionó la consulta que propuse, te comento que para mostrar sólo los temas que tienen enlace puedes hacerlo mediante los operadores ANY, EXISTS o IN. te pongo un ejemplo de cómo sería utilizando la sentencia ANY, pero te recomiendo que revises en alguno de los manuales que descargaste más acerca del uso de estas cláusulas.

Código SQL:
Ver original
  1. SELECT 1 AS nivel, T1.id, T1.nombre_tema AS descripcion FROM temas T1
  2. WHERE
  3. --Con esto muestras sólo los temas que tengan algún enlace
  4. T1.id = ANY (SELECT DISTINCT id_tema FROM sitios_web_por_tema W2)
  5. UNION
  6. SELECT 2 AS nivel, W.id_tema AS id, W.enlace_web AS descripcion
  7. FROM sitios_web_por_tema W INNER JOIN temas T2 ON W.id_tema = T2.id
  8. WHERE
  9. idioma = '5'
  10. --Falta agregar la condición para id_concepto
  11. ORDER BY id, nivel, descripcion

Como verás estoy tomando la misma consulta que propuse al inicio, si tuviste que hacer alguna adecuación adicional para que te funcionara pues debes volver a aplicarla.

Y un comentario adicional a lo que mencionaba el compañero gnzsoloyo

Cita:
Respecto al ejemplo propuesto por leonardo_josué, lamento advertirte que lo que te traerá será esto:

Código:
nivel|id|descripcion
------------------------
1|1|Tema 1 
1|2|Tema 2
1|3|Tema 3 
2|1|Enlace 1 
2|1|Enlace 2 
2|1|Enlace 3 
2|2|Enlace 4 
2|2|Enlace 5 
2|2|Enlace 6

porque en un UNION, el último ORDER BY afecta la totalidad de la tabla devuelta y no una parte de ella, por lo que ordenará las dos primeras columnas de todos los registros primero.
Efectivamente como lo comentas el orden se aplica en la total de la tabla pero creo que no revisaste la secuencia de ordenación que estoy manejando, si observas primero se ordena por el ID y después por el nivel, de tal manera que los campos se presentan tal y como lo puse en el post:

Código:
nivel|id|descripcion
------------------------
1|1|Tema 1
2|1|Enlace 1
2|1|Enlace 2
2|1|Enlace 3
1|2|Tema 2
2|2|Enlace 4
2|2|Enlace 5
2|2|Enlace 6
1|3|Tema 3
Un saludo
Leo.
  #10 (permalink)  
Antiguo 14/10/2010, 09:15
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Muchas gracias chicos

Leo: tu código salió perfecto!!!!!!!! Porfa si tienes un dato de un libro o un manual más detallado me sería de gran ayuda (los que tengo parecen ser un poco más sencillos).

A los dos un abrazo muy grande y muchísimas gracias por su ayuda.


:

  #11 (permalink)  
Antiguo 14/10/2010, 12:33
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Hola de nuevo modeff, recomendarte un libro es difícil, como comenta gnzsoloyo lo mejor sería que tomaras algún curso de SQL o en su defecto busques algo para principiantes. También te recomendaría que consideres la ayuda en línea que te proporciona el DMBS que manejes y en el último de los casos pues están los foros para tratar de resolver dudas.

Saludos.
Leo.
  #12 (permalink)  
Antiguo 14/10/2010, 13:59
 
Fecha de Ingreso: octubre-2008
Ubicación: españa
Mensajes: 33
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Al cruzar tablas necesito que arroje una vez el campo en común

Muchas gracias de todas maneras.

Saludos chicos,
Son muy generosos.


Etiquetas: tablas, campos
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 12:23.