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

Union de filas de parametros HIJOS

Estas en el tema de Union de filas de parametros HIJOS en el foro de Mysql en Foros del Web. Hola tengo que hacer una consulta que me esta dando guerra, y no lo resuelvo. Simplificando al maximo la cosa seria: TABLA productos: Código: id ...
  #1 (permalink)  
Antiguo 03/04/2016, 14:22
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Union de filas de parametros HIJOS

Hola tengo que hacer una consulta que me esta dando guerra, y no lo resuelvo.

Simplificando al maximo la cosa seria:
TABLA productos:
Código:
id  id_PADRE  Texto             familia
1   0         percha            1
2   0         libro             2
3   0         tenedor           2
4   -1        camisa            2
5   4         camisa azul       2
6   0         flores            2   
7   0         cuchara           2
8   4         camisa verde      2
Lo que quiero es por ejemplo seleccionar de FAMILIA = 2 y que os id_PADRE <1
y si encuentran un id_PADRE = -1 entonces busque los artículos que id_PADRE = id
y que ordene por Texto Ascendente.

El resultado buscado es:
Código:
id  id_PADRE  Texto             familia
4   -1        camisa            2
5   4         camisa azul       2
8   4         camisa verde      2
7   0         cuchara           2
6   0         flores            2  
2   0         libro             2
3   0         tenedor           2
El primer SELECT seria:
Código SQL:
Ver original
  1. SELECT
  2. p.id,p.id_PADRE,p.Texto
  3. FROM productos p
  4. WHERE p.id_PADRE<1 AND p.familia=2
  5. ORDER BY p.Texto

Con este select, obtendría:
Código:
id  id_PADRE  Texto             familia
4   -1        camisa            2
7   0         cuchara           2
6   0         flores            2   
2   0         libro             2
3   0         tenedor           2
Lo que necesito es en SQL si id_PADRE=-1 que busque las filas con id_PADRE=id
para que a continuación de la primera linea ponga:
Código:
id  id_PADRE  Texto             familia
5   4         camisa azul       2
8   4         camisa verde      2
alguna idea???

He mirado UNION, con JOIN, pero no doy con la formula.

GRACIAS!!!

Última edición por gnzsoloyo; 03/04/2016 a las 14:53
  #2 (permalink)  
Antiguo 03/04/2016, 14:57
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, 11 meses
Puntos: 774
Respuesta: Union de filas de parametros HIJOS

Con un simple query no vas a lograr eso, vas a tener que usar alguna funcion o un ciclo para recorrer los registros y hacer los ordenamientos como lo requieres, te diria que con una funcion recursiva, pero mysql no maneja recursividad :P
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 03/04/2016, 14: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, 7 meses
Puntos: 2658
Respuesta: Union de filas de parametros HIJOS

Cita:
Lo que quiero es por ejemplo seleccionar de FAMILIA = 2 y que os id_PADRE <1
y si encuentran un id_PADRE = -1 entonces busque los artículos que id_PADRE = id
Lamento decirte que lo que dices no tiene sentido. Es una condición de cumplimiento imposible, dado que en tu tabla ejemplo no existe ningún ID que sea -1.

Empieza por explicarnos qué es lo que representa ese "ID_PADRE", porque no parece relacionarse con nada.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 03/04/2016, 15:00
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Y con UNION y algun ORDER BY... con una función recursiva desde PHP puedo, pero me complica las cosas en la paginación, y las cargas de trabajo en el servidor porque la BBDD es grande, y combina tablas bastante gordas...

Alguna idea?
  #5 (permalink)  
Antiguo 03/04/2016, 15:14
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Lamento decirte que lo que dices no tiene sentido. Es una condición de cumplimiento imposible, dado que en tu tabla ejemplo no existe ningún ID que sea -1.

Empieza por explicarnos qué es lo que representa ese "ID_PADRE", porque no parece relacionarse con nada.
Perdon ME EXPLICQUE MAL
Si una fila id_PADRE=-1 entonces busco en esa misma Tabla
los id_PADRE IGUALES al id DE DICHA FILA.

En el ejemplo que pongo:
Código:
4   -1        camisa            2
entonces busco las filas con id_PADRE=4 que son:
Código:
5   4         camisa azul       2
8   4         camisa verde      2
  #6 (permalink)  
Antiguo 03/04/2016, 15:49
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, 7 meses
Puntos: 2658
Respuesta: Union de filas de parametros HIJOS

Código MySQL:
Ver original
  1. SELECT p1.id, p1.id_PADRE, p1.Texto
  2. FROM productos p1 INNER JOIN productos p2 ON p1.id = p2.id
  3. WHERE p2.id_PADRE = -1 AND p2.familia=2
  4. ORDER BY p1.Texto

Lo que sigue sin tener sentido es que tengas un "ID_PADRE" que pueda tener un valor negativo... ¿Por qué usas un -1?
__________________
¿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 03/04/2016, 15:58
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Acabo de dar con una SOLUCION!!!

Creo 2 campos "fantasma" que los uso para el orden.
El primero es idX que toma el valor de id siempre a menos que id_PADRE sea >0

Luego un campo textoX que contiene el texto de un select del idX

Con eso puedo ordenar por textoX y despues idX y despues por id_PADRE
al tener id_PADRE con -1 este queda siempre ARRIBA

Os pongo el codigo:
Código SQL:
Ver original
  1. SELECT
  2. *,
  3. (CASE
  4. WHEN id_PADRE < 1 THEN id
  5. ELSE id_PADRE
  6. END) idX,
  7. (SELECT ppp.Texto FROM productos ppp WHERE ppp.id=idX) textoX
  8. FROM productos p
  9. ORDER BY
  10. textoX DESC,
  11. idX ASC,
  12. p.id_PADRE ASC
o en orden inverso:
Código SQL:
Ver original
  1. SELECT
  2. *,
  3. (CASE
  4. WHEN id_PADRE < 1 THEN id
  5. ELSE id_PADRE
  6. END) idX,
  7. (SELECT ppp.Texto FROM productos ppp WHERE ppp.id=idX) textoX
  8. FROM productos p
  9. ORDER BY
  10. textoX ASC,
  11. idX ASC,
  12. p.id_PADRE ASC
[/CODE]

De esta forma puedo ordenar por TextoX de forma ascendente o descendente que id idPADRE = -1 (que es el padre de los hijos) esta por encima de los hijos, y estos a continuación.

Última edición por gnzsoloyo; 03/04/2016 a las 16:17
  #8 (permalink)  
Antiguo 03/04/2016, 16:18
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, 7 meses
Puntos: 2658
Respuesta: Union de filas de parametros HIJOS

¿Por qué no lees lo que se te responde?

__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 03/04/2016, 16:28
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Hola gracias por tu aporte, pero no da el resultado que busco.

El código que he publicado si resuelve lo que necesito.

GRACIAS
  #10 (permalink)  
Antiguo 03/04/2016, 16:37
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Os hago un resumen, con el código para hacer pruebas y que resuelve mi problema, por si sirve a alguien en el futuro....
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `productos` (
  2.   `id` int(11) NOT NULL AUTO_INCREMENT,
  3.   `id_PADRE` int(11) NOT NULL,
  4.   `Texto` varchar(50) CHARACTER SET latin1 NOT NULL,
  5.   `familia` int(11) NOT NULL,
  6.   PRIMARY KEY (`id`)
  7. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=9 ;
  8.  
  9.  
  10. INSERT INTO `productos` (`id`, `id_PADRE`, `Texto`, `familia`) VALUES
  11. (1, 0, 'percha', 1),
  12. (2, 0, 'libro', 2),
  13. (3, 0, 'tenedor', 2),
  14. (4, -1, 'camisa', 2),
  15. (5, 4, 'camisa azul', 2),
  16. (6, 0, 'flores', 2),
  17. (7, 0, 'camisa rosa', 2),
  18. (8, 4, 'camisa verde', 2);

Esta consulta es la que extrae el resultado como quiero.
La idea es que existen líneas que son PADRE y su valor id_PADRE es -1

Luego sus hijos en la columna id_PADRE apunta al id de su padre.

El objetivo es que al listar los hijos siempre salgan a continuación del padre independientemente del orden.

Haciendo una búsqueda recurrente desde Php podía, pero era un lio a la hora de paginar y ver totales de líneas etc.

Esta solución funciona.

Código MySQL:
Ver original
  1. *,
  2. WHEN id_PADRE < 1 THEN id
  3. ELSE id_PADRE
  4. END) idX,
  5. (SELECT ppp.Texto FROM productos ppp WHERE ppp.id=idX) textoX
  6.  
  7. FROM productos p
  8.  
  9. textoX DESC,
  10. idX ASC,
  11. p.id_PADRE ASC

GRACIAS

Última edición por gnzsoloyo; 03/04/2016 a las 20:16
  #11 (permalink)  
Antiguo 03/04/2016, 20:14
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, 7 meses
Puntos: 2658
Respuesta: Union de filas de parametros HIJOS

Cita:
Iniciado por Pentaxeros Ver Mensaje
Hola gracias por tu aporte, pero no da el resultado que busco.

El código que he publicado si resuelve lo que necesito.

GRACIAS
Tu código es innecesariamente complicado.
Simplemente deberías haber respondido que no obtenías el resultado esperado.

Este es más eficiente que todo eso que pones:

Código MySQL:
Ver original
  1. SELECT  p1.id, p1.id_PADRE, p1.Texto
  2. FROM productos p1
  3.     id_padre IN (SELECT  id
  4.                     FROM productos p2
  5.                     WHERE p2.id_PADRE = - 1 AND p2.familia = 2)
  6. ORDER BY p1.Texto;

Con este resultado:

Código MySQL:
Ver original
  1. mysql> SELECT  p1.id, p1.id_PADRE, p1.Texto
  2.     -> FROM productos p1
  3.     -> WHERE
  4.     ->     id_padre IN (SELECT  id
  5.     ->                     FROM productos p2
  6.     ->                     WHERE p2.id_PADRE = - 1 AND p2.familia = 2)
  7.     -> ORDER BY p1.Texto;
  8. +----+----------+--------------+
  9. | id | id_PADRE | Texto        |
  10. +----+----------+--------------+
  11. |  5 |        4 | camisa azul  |
  12. |  8 |        4 | camisa verde |
  13. +----+----------+--------------+
  14. 2 rows in set (0.00 sec)

El código de una consulta no solo debe devolver algo que se espera. También debe ser reducido, eficiente y optimizado.

Tu código devuelve esto:

Código MySQL:
Ver original
  1. +----+----------+--------------+---------+-----+-------------+
  2. | id | id_PADRE | Texto        | familia | idX | textoX      |
  3. +----+----------+--------------+---------+-----+-------------+
  4. |  3 |        0 | tenedor      |       2 |   3 | tenedor     |
  5. |  1 |        0 | percha       |       1 |   1 | percha      |
  6. |  2 |        0 | libro        |       2 |   2 | libro       |
  7. |  6 |        0 | flores       |       2 |   6 | flores      |
  8. |  7 |        0 | camisa rosa  |       2 |   7 | camisa rosa |
  9. |  4 |       -1 | camisa       |       2 |   4 | camisa      |
  10. |  5 |        4 | camisa azul  |       2 |   4 | camisa      |
  11. |  8 |        4 | camisa verde |       2 |   4 | camisa      |
  12. +----+----------+--------------+---------+-----+-------------+
  13. 8 rows in set (0.00 sec)

Tienes datos redundantes y entremezclados.
__________________
¿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; 03/04/2016 a las 20:21
  #12 (permalink)  
Antiguo 04/04/2016, 00:50
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Hola, no terminas de entender lo que quiero.
Necesito una consulta que me muestre todos los artículos únicos que son los que id_PADRE es valor < 1

Y en esa lista cuando encuentra un id_PADRE valor -1, me liste a continuación sus hijos.

Este ejemplo es un resumen muy sencillo de lo que tengo montado.
Es una base de datos de almacén, donde tengo artículos ÚNICOS, y artículos que están relacionados que dependen de una familia de su padre porque por ejemplo tienen tallas medidas etc pero que cada uno realmente es un artículo independiente pero cuelgan de su padre.

Esto, me permite listar el almacen y que los artículos HIJOS estén siempre a continuación del padre.

Mi consulta es la única forma de conseguir esa lista ordenada de esta forma por medio de crear 2 campos en la consulta.

Si ves una forma de conseguír el mismo resultado que yo (la comluma idX y textos son para mi solo la forma de conseguir el orden que deseo...) te lo agradecería.

Saludos
  #13 (permalink)  
Antiguo 04/04/2016, 07:12
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, 7 meses
Puntos: 2658
Respuesta: Union de filas de parametros HIJOS

Cita:
Lo que necesito es en SQL si id_PADRE=-1 que busque las filas con id_PADRE=id
para que a continuación de la primera linea ponga:
Código:
id  id_PADRE  Texto             familia
5   4         camisa azul       2
8   4         camisa verde      2
En principio, lo que te propongo devuelve esos dos registros con precisión. Solo resta lo que dices al principio: Poner al padre también, pero al principio.
Pero para eso debes entender una cosa: Las condiciones de esas consultas son incompatibles, por lo que no hay una query simple para devolverte eso, debido a que MySQL no cuenta con consultas recursivas como las de Oracle.
Para lograr algo como lo que deseas simplemente debes hacer una combinación de las dos condiciones por medio de un UNION:

Código MySQL:
Ver original
  1. mysql> SELECT  id, id_PADRE, Texto, familia
  2.     -> FROM productos p2
  3.     -> WHERE p2.id_PADRE = - 1 AND p2.familia = 2
  4.     -> UNION ALL
  5.     -> SELECT id, id_PADRE, TExto, familia
  6.     -> FROM
  7.     ->     (SELECT p1.id, p1.id_PADRE, p1.Texto, p1.familia
  8.     ->     FROM productos p1
  9.     ->     WHERE id_padre IN (SELECT  id
  10.     -> FROM productos p2
  11.     -> WHERE p2.id_PADRE = - 1 AND p2.familia = 2)
  12.     -> ORDER BY p1.Texto) tabla2;
  13. +----+----------+--------------+---------+
  14. | id | id_PADRE | Texto        | familia |
  15. +----+----------+--------------+---------+
  16. |  4 |       -1 | camisa       |       2 |
  17. |  5 |        4 | camisa azul  |       2 |
  18. |  8 |        4 | camisa verde |       2 |
  19. +----+----------+--------------+---------+
  20. 3 rows in set (0.00 sec)

Tal vez te preguntes por qué esta query es mejor que la que propones tu. Bueno la respuesta es simple: PERFORMANCE.

No solo estoy obteniendo exactamente lo que se busca, sino que además la performance de un CASE en el SELECT, en el caso de MySQL, es baja, y empeora a medida que hay mas datos.

No siempre la consulta mas simple de escritura es la que posee mejor performance.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 04/04/2016, 07:25
Avatar de Pentaxeros  
Fecha de Ingreso: mayo-2008
Mensajes: 173
Antigüedad: 16 años, 2 meses
Puntos: 3
Respuesta: Union de filas de parametros HIJOS

Gracias, pero NECESITO que en esa misma consulta esten tambien las lineas con id_PADRE=0.

cuando liste el almacen tengo que listar los articulos UNICOS, y los articulos PADRE siempre con sus hijos a continuacion, indemedientemente del orden que aplique.

Haciendo un buble de forma recursiva el facil, porque haces un SELECT normal, de id_PADRE <1 y cuando encuentro un id_PADRE=1, pues hago un SELECT nuevo con id_PADRE = al id de la fila que estoy.
Problema es que la paginacion es un rollo, y que las cargas del servidor son grandes.

De esta forma (LA QUE HE ENCONTRADO YO) puedo paginar facilmente desde sql, y por las pruebas de rendimiento con una BBDD con 30000 lineas cruzando datos ademas con otras tablas, el rendimiento es optimo.

NO OBSTANTE SI CONSIGUES o SABES como hacerlo mas optimo, te lo agradezco. Pero necesito que el resultado sea en esta linea, por ejemplo si ordena por Texto ASC.
Código:
id  id_PADRE  Texto             familia
4   -1        camisa            2
5   4         camisa azul       2
8   4         camisa verde      2
7   0         cuchara           2
6   0         flores            2  
2   0         libro             2
3   0         tenedor           2
El orden que salen los HIJOS (el id 5 y 8 ) me da igual, son los HIJOS, pero el padre debe estar en ORDEN, y SIEMPRE sus hijos a continuación.

Saludos!

Etiquetas: filas, hijos, join, parametros, select, sql, tabla, union
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 00:22.