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

Conflicto en ordernacion [Hierarchical data]

Estas en el tema de Conflicto en ordernacion [Hierarchical data] en el foro de Mysql en Foros del Web. Hola gente, tengo un pequeño problema el cual me esta dando lata. Cuento un poco el contexto, Estoy trabajando en un sistema de comentarios en ...
  #1 (permalink)  
Antiguo 14/12/2009, 16:20
Avatar de TMeister
Crazy Coder
 
Fecha de Ingreso: enero-2002
Ubicación: En la Oficina
Mensajes: 2.880
Antigüedad: 22 años, 3 meses
Puntos: 193
Conflicto en ordernacion [Hierarchical data]

Hola gente, tengo un pequeño problema el cual me esta dando lata.

Cuento un poco el contexto, Estoy trabajando en un sistema de comentarios en el cual una respuesta puede tener múltiples respuestas con niveles ilimitados. como sabran los niveles pueden dar muchos dolores de cabeza, recursividades carga al server etc.

Estuve trabajando en un sistema en donde para facilitar las consultas agrege 2 campos lineage y deep para poder hacer el ordenamiento desde una solo consulta no importando los niveles existentes.

La estructura de la tabla obviando los demas campos que no importan por ahora es:


Código MySQL:
Ver original
  1. +--------------+--------------------+------+-----+---------+----------------+
  2. | Field        | Type               | Null | Key | Default | Extra          |
  3. +--------------+--------------------+------+-----+---------+----------------+
  4. | id           | int(10)            | NO   | PRI | NULL    | auto_increment |
  5. | parent_id    | int(10)            | YES  |     | NULL    |                |
  6. | lineage      | varchar(255)       | NO   |     | NULL    |                |
  7. | deep         | int(3)             | NO   |     | NULL    |                |
  8. +--------------+--------------------+------+-----+---------+----------------+

al momento de insertar un nuevo comentario sin padre la tabla queda asi:

Hola gente, tengo un pequeño problema el cual me esta dando lata.

Cuento un poco el contexto, Estoy trabajando en un sistema de comentarios en el cual una respuesta puede tener multiples respuestas con niveles ilimitados. como sabran los niveles pueden dar muchos dolores de cabeza, recursividadesm carga al server etc.

Estuve trabajando en un sistema en donde para facilitar las consultas agrege 2 campos lineage y deep para poder hacer el ordenamiento desde una solo consulta no importando los niveles existentes.

La estructura de la tabla obviando los demas campos que no importan por ahora es:



Código MySQL:
Ver original
  1. +----+-----------+----------+------+
  2. | id | parent_id | lineage  | deep |
  3. +----+-----------+----------+------+
  4. | 15 |      NULL | 15       |    0 |
  5. +----+-----------+----------+------+

En donde el lineage es el mismo que id el cual nos servirá para despues hacer el ordenamiento.

Cuando este comentario a su vez recibe comentarios el resultado es este:

Código MySQL:
Ver original
  1. +----+-----------+----------+------+
  2. | id | parent_id | lineage  | deep |
  3. +----+-----------+----------+------+
  4. | 15 |      NULL | 15       |    0 |
  5. | 36 |        15 | 15-36    |    1 |
  6. | 34 |        15 | 15-34    |    1 |
  7. | 35 |        15 | 15-35    |    1 |
  8. | 68 |        34 | 15-34-68 |    2 |
  9. | 67 |        34 | 15-34-67 |    2 |
  10. | 16 |      NULL | 16       |    0 |
  11. | 17 |      NULL | 17       |    0 |
  12. | 18 |      NULL | 18       |    0 |
  13. | 19 |      NULL | 19       |    0 |
  14. +----+-----------+----------+------+

Esto es el resultado de la siguiente consulta
Código SQL:
Ver original
  1. SELECT c.id, c.parent_id, c.lineage, c.deep FROM comments AS c
  2. WHERE c.note_id = 157 AND c.STATUS = 'publish' ORDER BY c.lineage + 0 LIMIT 0,10;

Aquí viene el problema, el order by c.lineage lo hace relativamente bien.

Como podrán ver estoy forzando al ordenamiento numérico con el + 0 pero el resultado no es el deseado.

Ahora haciendo el ordenamiento natural obtengo:

Código SQL:
Ver original
  1. SELECT c.id, c.parent_id, c.lineage, c.deep FROM comments AS c
  2. WHERE c.note_id = 157 AND c.STATUS = 'publish' ORDER BY c.lineage LIMIT 0,10;

Código MySQL:
Ver original
  1. +-----+-----------+----------+------+
  2. | id  | parent_id | lineage  | deep |
  3. +-----+-----------+----------+------+
  4. | 100 |      NULL | 100      |    0 |
  5. |  15 |      NULL | 15       |    0 |
  6. |  34 |        15 | 15-34    |    1 |
  7. |  67 |        34 | 15-34-67 |    2 |
  8. |  68 |        34 | 15-34-68 |    2 |
  9. |  35 |        15 | 15-35    |    1 |
  10. |  36 |        15 | 15-36    |    1 |
  11. |  16 |      NULL | 16       |    0 |
  12. |  17 |      NULL | 17       |    0 |
  13. |  18 |      NULL | 18       |    0 |
  14. +-----+-----------+----------+------+

Ahora el lineage "interno" es decir los 15-34-67 los ordena bien PERO el orden pone al 100 menor que el 15

El ordenamiento esperado es:

Código MySQL:
Ver original
  1. +----+------------+----------+------+
  2. | id  | parent_id | lineage  | deep |
  3. +----+------------+----------+------+
  4. |  15 |      NULL | 15       |    0 |
  5. |  36 |        15 | 15-36    |    1 |
  6. |  34 |        15 | 15-34    |    1 |
  7. |  68 |        34 | 15-34-68 |    2 |
  8. |  67 |        34 | 15-34-67 |    2 |
  9. |  35 |        15 | 15-35    |    1 |
  10. |  16 |      NULL | 16       |    0 |
  11. |  17 |      NULL | 17       |    0 |
  12. |  18 |      NULL | 18       |    0 |
  13. |  19 |      NULL | 19       |    0 |
  14. | 100 |      NULL | 100      |    0 |
  15. +-----+-----------+----------+------+

Alguna idea al respecto??

Umm tal vez haciendo un order by id and order by lineage, eso se me ocurrió en este momento pruebo y vuelvo aunque de todos modos dejo el post por si alguien quiere echar una mano..

Saludos!
  #2 (permalink)  
Antiguo 14/12/2009, 16:32
Avatar de Vun
Vun
Colaborador
 
Fecha de Ingreso: agosto-2009
Ubicación: Benalmádena, España
Mensajes: 2.265
Antigüedad: 14 años, 8 meses
Puntos: 150
Respuesta: Conflicto en ordernacion [Hierarchical data]

Tu solucion esta clara!! guarda los ids de lineage con 3 cifras (o mas) forzosamente, es decir algo asi:

100
015
015-036
015-014
015-034-068

De esa forma al ordenarlo alfanumericamente lo vas a tener como quieres ya que 015 va antes que 100.

De hecho yo uso esta funcion en mi juego para algo muy similar a lo que tu dices:

Código PHP:
// Funcion que agrega ceros a la izquierda de otra variable segun longitud dada
function agregaceros($longitud,$variable) {
    return 
str_repeat("0",$longitud-strlen($variable)).$variable;

  #3 (permalink)  
Antiguo 14/12/2009, 16:38
Avatar de GeoAvila
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Antigua Guatemala
Mensajes: 4.032
Antigüedad: 20 años, 4 meses
Puntos: 53
Respuesta: Conflicto en ordernacion [Hierarchical data]

bueno sería algo así

Código MySQL:
Ver original 

nos vemos.
__________________
* Antes de preguntar lee las FAQ, y por favor no hagas preguntas en las FAQ
Sitio http://www.geoavila.com twitter: @GeoAvila
  #4 (permalink)  
Antiguo 14/12/2009, 16:42
 
Fecha de Ingreso: diciembre-2009
Mensajes: 1
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Conflicto en ordernacion [Hierarchical data]

has probado, usando tambien deep?

SELECT c.id, c.parent_id, c.lineage, c.deep FROM comments AS c
WHERE c.note_id = 157 AND c.STATUS = 'publish' ORDER BY c.lineage,c.deep LIMIT 0,10;
  #5 (permalink)  
Antiguo 14/12/2009, 16:48
Avatar de TMeister
Crazy Coder
 
Fecha de Ingreso: enero-2002
Ubicación: En la Oficina
Mensajes: 2.880
Antigüedad: 22 años, 3 meses
Puntos: 193
Respuesta: Conflicto en ordernacion [Hierarchical data]

@Vun suena lógica esa solución Voy a probar a ver que tal.

@GeoAvila Ahi estamos forzando el ordenamiento a que sea numerico que exactamente igual que lo que hago con el order by lineage + 0 da el mismo resultado.

Gracias a ambos.. ya les cuento.
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 10:07.