Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-04-2007
PatrickM PatrickM is offline
Miembro
 
Registrado: jun 2006
Posts: 21
Poder: 0
PatrickM Va por buen camino
Consulta SQL para estructura en arbol

Hola amigos,

Tengo un problema de SQL que se me resiste. A ver si alguien me puede dar la solución. Tengo una tabla que me representa una estructura en arbol, como un arbol de directorios donde de un elemento le pueden colgar otros. Bien la tabla que tengo definida es como la siguiente:

CREATE TABLE Estructura (
CODIGO INTEGER,
DESCRIPCION VARCHAR(100),
CODIGO_PADRE INTEGER,
NIVEL INTEGER,
PRIMARY KEY(CODIGO)
)

Con esta tabla he conseguido tiempos de carga muy optimos utilizando el concepto de NIVELm y utilizando una sola consulta.

El problema que se me plantea ahora es que quiero saber a partir de un elemento, cual es su padre, su abuelo, su visabuelo, y asi hasta el que llegue al elemento raiz. Esto se puede hacer haciendo una funcion recursiva via codigo Delphi, pero es muy costoso en tiempo, i mas si lo que quiero es hacer para N elementos del arbol.

¿Alguien sabe como hacerlo con una sola consulta??
Responder Con Cita
  #2  
Antiguo 16-04-2007
Avatar de kuan-yiu
[kuan-yiu] kuan-yiu is offline
Miembro Premium
 
Registrado: jun 2006
Ubicación: Galicia. España.
Posts: 1.017
Poder: 19
kuan-yiu Va camino a la fama
El problema del acceso óptimo a los árboles de datos tiene años y varias aproximaciones (que no soluciones). Yo lo di en varias asignaturas de la carrera y ahora mismo recuerdo 3 o 4 métodos, pero sólo a nivel teórico. Supongo que si buscas un poco encontrarás mucha documentación, pero yo no confiaría demasiado en encontrar ejemplos prácticos.
Responder Con Cita
  #3  
Antiguo 16-04-2007
PatrickM PatrickM is offline
Miembro
 
Registrado: jun 2006
Posts: 21
Poder: 0
PatrickM Va por buen camino
gracias por tu respuesta. A nivel teorico se que hay aproximaciones al problema, pero me gustaria saber si alguien ha encontrado la solución a mi problema con una sola consulta SQL.

En código delphi lo resolveria con una funcion recursiva, que como mucho se ejecutaria un numero de veces menor o igual a la altura del arbol. Algo similar a esto:

Código Delphi [-]
function DevuelveHerencia(Codigo: integer): integer;
   begin
     If codigo<>-1 Then Begin
       SentenciaSQL;
       GuardarCodigo(Codigo);
       DevuelveHerencia(Codigo_Padre);
     End;
   end;

El problema esta si quiero saber la Herencia de un conjunto de elementos del arbol. Entonces necesitaria ejecutar tantas sentencias SQL como Elementos tubiera, y esto multiplicado por la altura del arbol, es decir un coste N*Altura hablando en llamadas SQL, mientras que yo busco un coste 1.

Última edición por PatrickM fecha: 16-04-2007 a las 19:52:58.
Responder Con Cita
  #4  
Antiguo 16-04-2007
Avatar de kuan-yiu
[kuan-yiu] kuan-yiu is offline
Miembro Premium
 
Registrado: jun 2006
Ubicación: Galicia. España.
Posts: 1.017
Poder: 19
kuan-yiu Va camino a la fama
A nivel teórico es imposible conseguir un coste uno, salvo que puedas leer TODA la estructura del arbol de una sola vez, pero eso crea un problema de manejo de la información en memoria.
Creo recordar cierto método para leer toda una rama, que es lo que creo que tú quieres, pero se apoya en una estructura diferente de la que tienes.
Responder Con Cita
  #5  
Antiguo 16-04-2007
PatrickM PatrickM is offline
Miembro
 
Registrado: jun 2006
Posts: 21
Poder: 0
PatrickM Va por buen camino
Hola kuan-yiu,

Cuando hablo de coste 1 no me refiero a coste de proceso O(1) como el que se habla en la teoria. Me refiero a coste 1 consulta SQL, en vez de N*Altura consultas SQL.

El coste en tiempo mas critico que hay en lanzar una consulta es el tiempo que se tarda entre que el Cliente lanza una consulta y el Servidor devuelve un resultado, por eso el Coste real de proceso no me importa ya que es infimo en comparación al coste de enviar la información por la red.

En temas de memoria el Servidor de Base de Datos tiene toda la información disponible, o sea que tampoco es problema, y tienes toda la estructura del arbol disponible, ya que esta se guarda integramente en una sola tabla de la Base de Datos.
Responder Con Cita
  #6  
Antiguo 16-04-2007
Avatar de kuan-yiu
[kuan-yiu] kuan-yiu is offline
Miembro Premium
 
Registrado: jun 2006
Ubicación: Galicia. España.
Posts: 1.017
Poder: 19
kuan-yiu Va camino a la fama
Lo he pensado y no se me ocurre una única consulta en la que puedas conseguirlo todo , pero creo que la recursividad no es la mejor idea en este caso. Me parece que haciendo la consulta dentro de un bucle y utilizando el nivel como condición de ruptura funcionaría mejor que con recursividad.

Lamento no poder ayudarte.
Responder Con Cita
  #7  
Antiguo 16-04-2007
PatrickM PatrickM is offline
Miembro
 
Registrado: jun 2006
Posts: 21
Poder: 0
PatrickM Va por buen camino
Ya, la funcion recursiva en Delphi no es la mejor solución, ya que para cada llamada recursiva estoy haciendo una llamada SQL; pero de momento es la unica solución que he encontrado. Yo creo que la solución pasa por hacer algo recursivo pero en SQL, para que se ejecute dentro del Servidor de Bases de Datos.

A ver si alguien se anima y encuentra una solución.

Gracias de todas formas kuan-yiu.
Responder Con Cita
  #8  
Antiguo 16-04-2007
hach hach is offline
Miembro
 
Registrado: mar 2007
Ubicación: Bariloche, Argentina
Posts: 44
Poder: 0
hach Va por buen camino
procedimiento almacenado?

hola,
que base de datos usas?
en Firebird podrias hacer un procedure, que realice una consulta de toda la tabla y recorriendo los datos retornes solo los que te interesan
Como todo el trabajo lo hace el servidor no hay costo de transferencia de datos

la consulta SQl desde delphi seria algo asi como

select * from sp_rama_herencia(nodo_actual)

Saludos, espero que te sirva...
Responder Con Cita
  #9  
Antiguo 16-04-2007
PatrickM PatrickM is offline
Miembro
 
Registrado: jun 2006
Posts: 21
Poder: 0
PatrickM Va por buen camino
Gracias hach, creo que esto podria servir!

Aunque se me complica un poco el tema, ya que la aplicación usa tanto una Base de Datos Oracle como un SQL Server; es configurable externamente. Ya hago algunos cambios en los SQL antes de mandarlos a la BD para tener en cuenta los cambios en la sintaxis, pero aquí creo que seran muchos mas.
Responder Con Cita
  #10  
Antiguo 16-04-2007
hach hach is offline
Miembro
 
Registrado: mar 2007
Ubicación: Bariloche, Argentina
Posts: 44
Poder: 0
hach Va por buen camino
no creo que tengas problemas

no creo que tengas problemas, creo que ambas bases soportan procedures
La llamada desde delphi posiblemente cambie, y tal vez la sintaxis del procedure, pero deberias poder
Responder Con Cita
  #11  
Antiguo 16-04-2007
Avatar de xander
xander xander is offline
Miembro
 
Registrado: jul 2006
Posts: 499
Poder: 18
xander Va por buen camino
Definitivamente unProcedimiento Almacenado es lo que necesitas, solo recuerda hacer indices por los campos CODIGO y CODIGO_PADRE para optimizar el acceso a cada nodo, yo lo tengo hecho así para una aplicación con un arbol enorme (varios cientos de miles de registros) y todo funciona a la perfección.

Tambien claro que al mostrar el arbol en un TTreeView no se cargan todos los datos de golpe sino que los voy cargando por "Niveles" y por "Padre Comun" asi solo se traen de la BD los registros que se van solicitando.
__________________
"Hey, nena, debe ser genial ser tú y verme a mí mismo..."
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Árbol php halizia PHP 4 20-12-2006 15:42:57
mp3 dañado? Componente para arreglar la estructura coletaun Varios 0 30-11-2006 17:56:15
arbol en TTreeView elguille77 Varios 1 08-11-2006 00:30:33
consulta con dos tablas con misma estructura AbcXxx SQL 8 30-06-2006 22:06:13
Es posible para solo la estructura de la base de datos de ib expert a Access Nelly Varios 3 10-02-2006 08:37:59


La franja horaria es GMT +2. Ahora son las 08:07:40.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi