RESUELVE - MySql conjuntos anidados - Encuentra "hojas"

  • righteous_trespasser
  • Scuffle
  • Genius
  • Avatar de Usuario
  • Registrado: Mar 12, 2007
  • Mensajes: 6228
  • Loc: South-Africa
  • Status: Offline

Nota Junio 29th, 2010, 7:07 am

Tengo el siguiente cuadro:

MYSQL Código: [ Select ]
CREATE TABLE task(
id INT(11) PRIMARY KEY NOT NULL REFERENCES `data`(id),
name VARCHAR(255) NOT NULL,
description TEXT NULL,
start_date DATETIME NULL,
end_date DATETIME NULL,
lft INT(11) NOT NULL,
rgt INT(11) NOT NULL
) ENGINE=InnoDB;
  1. CREATE TABLE task(
  2. id INT(11) PRIMARY KEY NOT NULL REFERENCES `data`(id),
  3. name VARCHAR(255) NOT NULL,
  4. description TEXT NULL,
  5. start_date DATETIME NULL,
  6. end_date DATETIME NULL,
  7. lft INT(11) NOT NULL,
  8. rgt INT(11) NOT NULL
  9. ) ENGINE=InnoDB;


y con esta tabla tengo los siguientes datos como ejemplo:

Attachments:
data.gif

Las palabras son el nombre y el rojo muestra la lft "y" RGT "valores.

Para encontrar toda la "hoja" nodos que ejecute la siguiente consulta:

MYSQL Código: [ Select ]
SELECT node.name
FROM task AS parent, task AS node
JOIN `data` ON node.id = `data`.id
WHERE node.lft BETWEEN parent.lft AND parent.rgt
AND node.rgt = (node.lft + 1)
AND `data`.status = 'A'
GROUP BY node.name
ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC;
  1. SELECT node.name
  2. FROM task AS parent, task AS node
  3. JOIN `data` ON node.id = `data`.id
  4. WHERE node.lft BETWEEN parent.lft AND parent.rgt
  5. AND node.rgt = (node.lft + 1)
  6. AND `data`.status = 'A'
  7. GROUP BY node.name
  8. ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC;


Con que me sale el siguiente como resultado:
"Imágenes Buscar", "Sign Off", "blog", "usuario" y "Load Contenido".

Cada una de estas tareas "tienen un estado de" A "(para Active) en este momento (que se encuentra en el directorio` datos `tabla), pero digamos que" blog "y" Usuario "ahora los dos tienen un estado de" F "(para acabados). Entonces me gustaría ver lo siguiente como resultado:
"Imágenes Buscar", "Sign Off", "Carga de los módulos", "Contenido de carga".
Así que me gustaría encontrar todos los nodos de la hoja, pero si todos los nodos en un nodo tiene un estado de "F", Id gustaría ver ese nodo y no a los niños.

¿Es posible? Y si es sabes cómo hacerlo, porque estoy perdido.
Let's leave all our *plum* where it is and go live in the jungle ...
  • Anonymous
  • Bot
  • No Avatar
  • Registrado: 25 Feb 2008
  • Mensajes: ?
  • Loc: Ozzuland
  • Status: Online

Nota Junio 29th, 2010, 7:07 am

  • SpooF
  • ٩๏̯͡๏۶
  • Bronze Member
  • Avatar de Usuario
  • Registrado: May 22, 2004
  • Mensajes: 3415
  • Loc: Richland, WA
  • Status: Offline

Nota Junio 29th, 2010, 7:23 am

¿Se puede exportar la tabla con los datos? La enfermedad jugar con esto un poco, pero quiero asegurarme de que tengo los datos correctos.

Los valores de nodo secundario para la izquierda y la derecha siempre será entre las pare no izquierda y derecha, ¿correcto?
#define NULL (::rand() % 2)
  • righteous_trespasser
  • Scuffle
  • Genius
  • Avatar de Usuario
  • Registrado: Mar 12, 2007
  • Mensajes: 6228
  • Loc: South-Africa
  • Status: Offline

Nota Junio 29th, 2010, 7:36 am

Claro, aquí está el código:

MYSQL Código: [ Select ]
CREATE TABLE task(
id INT(11) PRIMARY KEY NOT NULL REFERENCES `data`(id),
name VARCHAR(255) NOT NULL,
description TEXT NULL,
start_date DATETIME NULL,
end_date DATETIME NULL,
lft INT(11) NOT NULL,
rgt INT(11) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE `data`(
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
created_date DATETIME NULL,
last_modified_date DATETIME NULL,
type VARCHAR(255) NOT NULL,
status CHAR(1) NOT NULL DEFAULT 'P',
url VARCHAR(255) NOT NULL,
view_count INT(11) NOT NULL DEFAULT 0
) ENGINE=InnoDB;
INSERT INTO `data` VALUES(1,NOW(),NOW(),'Task','A','project',0),(2,NOW(),NOW(),'Task','A','design',0),(3,NOW(),NOW(),'Task','A','find_images',0),(4,NOW(),NOW(),'Task','A','sign_off',0),(5,NOW(),NOW(),'Task','A','develop',0),(6,NOW(),NOW(),'Task','A','load_modules',0),(7,NOW(),NOW(),'Task','A','blog',0),(8,NOW(),NOW(),'Task','A','user',0),(9,NOW(),NOW(),'Task','A','load_content',0);
INSERT INTO task VALUES(1,'Project',null,null,null,1,18),(2,'Design',null,null,null,2,7),(3,'Find Images',null,null,null,3,4),(4,'Sign Off',null,null,null,5,6),(5,'Develop',null,null,null,8,17),(6,'Load Modules',null,null,null,9,14),(7,'Blog',null,null,null,10,11),(8,'User',null,null,null,12,13),(9,'Load Content',null,null,null,15,16);
  1. CREATE TABLE task(
  2. id INT(11) PRIMARY KEY NOT NULL REFERENCES `data`(id),
  3. name VARCHAR(255) NOT NULL,
  4. description TEXT NULL,
  5. start_date DATETIME NULL,
  6. end_date DATETIME NULL,
  7. lft INT(11) NOT NULL,
  8. rgt INT(11) NOT NULL
  9. ) ENGINE=InnoDB;
  10. CREATE TABLE `data`(
  11. id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  12. created_date DATETIME NULL,
  13. last_modified_date DATETIME NULL,
  14. type VARCHAR(255) NOT NULL,
  15. status CHAR(1) NOT NULL DEFAULT 'P',
  16. url VARCHAR(255) NOT NULL,
  17. view_count INT(11) NOT NULL DEFAULT 0
  18. ) ENGINE=InnoDB;
  19. INSERT INTO `data` VALUES(1,NOW(),NOW(),'Task','A','project',0),(2,NOW(),NOW(),'Task','A','design',0),(3,NOW(),NOW(),'Task','A','find_images',0),(4,NOW(),NOW(),'Task','A','sign_off',0),(5,NOW(),NOW(),'Task','A','develop',0),(6,NOW(),NOW(),'Task','A','load_modules',0),(7,NOW(),NOW(),'Task','A','blog',0),(8,NOW(),NOW(),'Task','A','user',0),(9,NOW(),NOW(),'Task','A','load_content',0);
  20. INSERT INTO task VALUES(1,'Project',null,null,null,1,18),(2,'Design',null,null,null,2,7),(3,'Find Images',null,null,null,3,4),(4,'Sign Off',null,null,null,5,6),(5,'Develop',null,null,null,8,17),(6,'Load Modules',null,null,null,9,14),(7,'Blog',null,null,null,10,11),(8,'User',null,null,null,12,13),(9,'Load Content',null,null,null,15,16);
Let's leave all our *plum* where it is and go live in the jungle ...
  • righteous_trespasser
  • Scuffle
  • Genius
  • Avatar de Usuario
  • Registrado: Mar 12, 2007
  • Mensajes: 6228
  • Loc: South-Africa
  • Status: Offline

Nota Junio 29th, 2010, 7:47 am

SpooF escribió:
Los valores de nodo secundario para la izquierda y la derecha siempre será entre las pare no izquierda y derecha, ¿correcto?

Sí, tengo el ejemplo de aquí .
Let's leave all our *plum* where it is and go live in the jungle ...
  • joebert
  • Sledgehammer
  • Genius
  • No Avatar
  • Registrado: Feb 10, 2004
  • Mensajes: 13455
  • Loc: Florida
  • Status: Offline

Nota Junio 29th, 2010, 11:17 am

Vi este hilo hace un par de horas y perplejos fue. Estaba pensando en sub-consultas, pero no sabe donde va a ir con él. Después de tomar algo de comer pienso que tengo algo sin embargo.

SQL Código: [ Select ]
SELECT node.name
FROM task AS parent, task AS node
JOIN `data` ON node.id = `data`.id
WHERE
  (
   node.lft BETWEEN parent.lft AND parent.rgt
   AND node.rgt = (node.lft + 1)
   AND `data`.STATUS = 'A'
  )
  OR
  (
   node.lft IN (SELECT lft - 1 AS _lft FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
   AND node.rgt IN (SELECT rgt + 1 AS _rgt FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
  )
GROUP BY node.name
ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC
  1. SELECT node.name
  2. FROM task AS parent, task AS node
  3. JOIN `data` ON node.id = `data`.id
  4. WHERE
  5.   (
  6.    node.lft BETWEEN parent.lft AND parent.rgt
  7.    AND node.rgt = (node.lft + 1)
  8.    AND `data`.STATUS = 'A'
  9.   )
  10.   OR
  11.   (
  12.    node.lft IN (SELECT lft - 1 AS _lft FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
  13.    AND node.rgt IN (SELECT rgt + 1 AS _rgt FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
  14.   )
  15. GROUP BY node.name
  16. ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC
Strong with this one, the sudo is.
  • righteous_trespasser
  • Scuffle
  • Genius
  • Avatar de Usuario
  • Registrado: Mar 12, 2007
  • Mensajes: 6228
  • Loc: South-Africa
  • Status: Offline

Nota Junio 29th, 2010, 11:15 pm

Excelente. Gracias joebert, gracias falsos. Resuelto.
Let's leave all our *plum* where it is and go live in the jungle ...
  • righteous_trespasser
  • Scuffle
  • Genius
  • Avatar de Usuario
  • Registrado: Mar 12, 2007
  • Mensajes: 6228
  • Loc: South-Africa
  • Status: Offline

Nota Junio 30th, 2010, 1:55 am

Bueno, quizá no del todo. Acabo de comprobar esto un poco más lejos. Si termino "blog", "Usuario", "Módulos de carga", "cargar contenido" o "Buscar imágenes" y "firmar", entonces debe quedar con el "Diseño" y "Desarrollo". Sin embargo, me dejó con "Diseño", "Desarrollo" y "módulos de carga".

He cambiado la consulta a la siguiente para solucionar este tema:
MYSQL Código: [ Select ]
SELECT node.id,node.name
FROM task AS parent, task AS node
JOIN `data` ON node.id = `data`.id
WHERE
  (
   node.lft BETWEEN parent.lft AND parent.rgt
   AND node.rgt = (node.lft + 1)
   AND `data`.`status` = 'A'
  )
  OR
  (
   node.lft IN (SELECT lft - 1 AS _lft FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
   AND node.rgt IN (SELECT rgt + 1 AS _rgt FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
   AND `data`.`status` != 'F'
  )
GROUP BY node.name
ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC
  1. SELECT node.id,node.name
  2. FROM task AS parent, task AS node
  3. JOIN `data` ON node.id = `data`.id
  4. WHERE
  5.   (
  6.    node.lft BETWEEN parent.lft AND parent.rgt
  7.    AND node.rgt = (node.lft + 1)
  8.    AND `data`.`status` = 'A'
  9.   )
  10.   OR
  11.   (
  12.    node.lft IN (SELECT lft - 1 AS _lft FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
  13.    AND node.rgt IN (SELECT rgt + 1 AS _rgt FROM task LEFT JOIN `data` ON task.id = `data`.id WHERE `data`.STATUS = 'F')
  14.    AND `data`.`status` != 'F'
  15.   )
  16. GROUP BY node.name
  17. ORDER BY DATE(`data`.created_date),(COUNT(parent.name) - 1) DESC

Funciona con que también ahora.

Muchas gracias una vez más chicos.
Let's leave all our *plum* where it is and go live in the jungle ...

Publicar Información

  • Total de mensajes en este tema: 7 mensajes
  • Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 296 invitados
  • No puede abrir nuevos temas en este Foro
  • No puede responder a temas en este Foro
  • No puede editar sus mensajes en este Foro
  • No puede borrar sus mensajes en este Foro
  • No puede enviar adjuntos en este Foro
 
 

© 2011 Unmelted, LLC. Ozzu® es una marca registrada de Unmelted, LLC