Sql Recursivo Como ?

10/04/2007 - 23:22 por Mauricio Pulla | Informe spam
Hola.

Tengo la siguiente tabla de Itemes.

Item
iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int, iParent
Int

iItemId cItemId cDescripcion iGrupo iParent
1 01 Grupo 1 1
0
2 02 Grupo 2 1
0
3 01 Grupo 3 1
0
4 0101 SubGrupo 0101 1 1
5 0102 SubGrupo 0102 1 1
6 01010001 Item 01010001 0 4
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11
13 01010002 Item 01010002 0 4
14 01010003 Item 01010003 0 4
15 01010004 Item 01010004 0 4
16 01010005 Item 01010005 0 4
17 0102010102 Item 0102010102 0 11

Necesito crear un sql que muestre por ejemplo el registro No.:7 y todos los
resgistro que se relacionan de forma directa e indirecta con el:

iItemId cItemId cDescripcion
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11

17 0102010102 Item 0102010102 0 11

Seria muy facil:
Select * From Item Where substring(cItemId, 1, 4) = '010201'
Si es que la codificación seria automatica, si la codificacion se la da
manualmente o por codigo de barras ya no seria factible este sql.

Otro Sql seria
Select * From Item Where iItemId = 7
Union
Select * From Item Where iParent = 7

Pero solo traeria:

iItemId cItemId cDescripcion iGrupo iParent
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7

y los restantes registros tienen como iParent al registro 11 que depende del
regsitro 7
iItemId cItemId cDescripcion iGrupo iParent
12 0102010101 Item 0102010101 0 11
17 0102010102 Item 0102010102 0 11

El problema es algo complejo ya que el usuario puede crear los niveles que
creyera conveniente, y cItemId puede tener codigo de barras o caracteres que
no tengan nada que ver con el registro padre.

En todo caso espero su ayuda...

Saludos cordiales.
Mauricio Pulla
Cuenca-Ecuador

Preguntas similare

Leer las respuestas

#1 Javier Loria
10/04/2007 - 23:37 | Informe spam
Hola:
Si usas SQL 2005 el problema se puede resolver de forma sencilla una CTE
recursiva.
Si usas SQL 2000 es un poco mas complejo y sobre todo con un desempeño
mucho mas pobre.
Que version usas?

Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Mauricio Pulla" wrote in message
news:
Hola.

Tengo la siguiente tabla de Itemes.

Item
iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int,
iParent
Int

iItemId cItemId cDescripcion iGrupo iParent
1 01 Grupo 1 1
0
2 02 Grupo 2 1
0
3 01 Grupo 3 1
0
4 0101 SubGrupo 0101 1 1
5 0102 SubGrupo 0102 1 1
6 01010001 Item 01010001 0 4
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11
13 01010002 Item 01010002 0 4
14 01010003 Item 01010003 0 4
15 01010004 Item 01010004 0 4
16 01010005 Item 01010005 0 4
17 0102010102 Item 0102010102 0 11

Necesito crear un sql que muestre por ejemplo el registro No.:7 y todos
los
resgistro que se relacionan de forma directa e indirecta con el:

iItemId cItemId cDescripcion
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11

17 0102010102 Item 0102010102 0 11

Seria muy facil:
Select * From Item Where substring(cItemId, 1, 4) = '010201'
Si es que la codificación seria automatica, si la codificacion se la da
manualmente o por codigo de barras ya no seria factible este sql.

Otro Sql seria
Select * From Item Where iItemId = 7
Union
Select * From Item Where iParent = 7

Pero solo traeria:

iItemId cItemId cDescripcion iGrupo iParent
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7

y los restantes registros tienen como iParent al registro 11 que depende
del
regsitro 7
iItemId cItemId cDescripcion iGrupo iParent
12 0102010101 Item 0102010101 0 11
17 0102010102 Item 0102010102 0 11

El problema es algo complejo ya que el usuario puede crear los niveles que
creyera conveniente, y cItemId puede tener codigo de barras o caracteres
que
no tengan nada que ver con el registro padre.

En todo caso espero su ayuda...

Saludos cordiales.
Mauricio Pulla
Cuenca-Ecuador



Respuesta Responder a este mensaje
#2 Mauricio Pulla
10/04/2007 - 23:58 | Informe spam
Hola Javier.

Utilizo Sql 2000, se me hace dificil actualizarme a Sql 2005.

En todo caso te agradeceria mucho me ilumines un poco, para poder comenzar a
dar solucion a este problemilla.
Donde puedo leer sobre CTE.

Saludos cordiales,
Mauricio Pulla.
Cuenca-Ecuador.

"Javier Loria" escribió en el mensaje
news:
Hola:
Si usas SQL 2005 el problema se puede resolver de forma sencilla una
CTE recursiva.
Si usas SQL 2000 es un poco mas complejo y sobre todo con un desempeño
mucho mas pobre.
Que version usas?

Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Mauricio Pulla" wrote in message
news:
Hola.

Tengo la siguiente tabla de Itemes.

Item
iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int,
iParent
Int

iItemId cItemId cDescripcion iGrupo iParent
1 01 Grupo 1 1
0
2 02 Grupo 2 1
0
3 01 Grupo 3 1
0
4 0101 SubGrupo 0101 1 1
5 0102 SubGrupo 0102 1 1
6 01010001 Item 01010001 0 4
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11
13 01010002 Item 01010002 0 4
14 01010003 Item 01010003 0 4
15 01010004 Item 01010004 0 4
16 01010005 Item 01010005 0 4
17 0102010102 Item 0102010102 0 11

Necesito crear un sql que muestre por ejemplo el registro No.:7 y todos
los
resgistro que se relacionan de forma directa e indirecta con el:

iItemId cItemId cDescripcion
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11

17 0102010102 Item 0102010102 0 11

Seria muy facil:
Select * From Item Where substring(cItemId, 1, 4) = '010201'
Si es que la codificación seria automatica, si la codificacion se la da
manualmente o por codigo de barras ya no seria factible este sql.

Otro Sql seria
Select * From Item Where iItemId = 7
Union
Select * From Item Where iParent = 7

Pero solo traeria:

iItemId cItemId cDescripcion iGrupo iParent
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7

y los restantes registros tienen como iParent al registro 11 que depende
del
regsitro 7
iItemId cItemId cDescripcion iGrupo iParent
12 0102010101 Item 0102010101 0 11
17 0102010102 Item 0102010102 0 11

El problema es algo complejo ya que el usuario puede crear los niveles
que
creyera conveniente, y cItemId puede tener codigo de barras o caracteres
que
no tengan nada que ver con el registro padre.

En todo caso espero su ayuda...

Saludos cordiales.
Mauricio Pulla
Cuenca-Ecuador






Respuesta Responder a este mensaje
#3 Gustavo Larriera (MVP)
11/04/2007 - 00:37 | Informe spam
En SQL Server 2000 no puedes usar CTE (eso es de SS2005). Para resolver
problemas recursivos deberá hacerlo... iterativamente (sin recursión).

Mira estos artículos:

Recursive queries with SQL Server 2000
http://www.mssqltips.com/tip.asp?tip“8

http://www.vikramlakhotia.com/Worki...n_SQL_Serv
er_2000.aspx

Gustavo Larriera, MVP
Solid Quality
Blog: http://blogs.solidq.com/ES/glarriera
MVP Profile: https://mvp.support.microsoft.com/p...464A-F453-
4CFC-8F7E-C9BEADD8FB25
Este mensaje se proporciona tal como es, sin garantías de ninguna clase
/ This message is provided "AS IS" with no warranties expressed or
implied, and confers no rights.

In article ,
says...
Hola Javier.

Utilizo Sql 2000, se me hace dificil actualizarme a Sql 2005.

En todo caso te agradeceria mucho me ilumines un poco, para poder comenzar a
dar solucion a este problemilla.
Donde puedo leer sobre CTE.

Saludos cordiales,
Mauricio Pulla.
Cuenca-Ecuador.

"Javier Loria" escribió en el mensaje
news:
> Hola:
> Si usas SQL 2005 el problema se puede resolver de forma sencilla una
> CTE recursiva.
> Si usas SQL 2000 es un poco mas complejo y sobre todo con un desempeño
> mucho mas pobre.
> Que version usas?
>
> Javier Loria
> Costa Rica (MVP)
> Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
> que pueda ser copiado y pegado al Query Analizer.
> La version de SQL y Service Pack tambien ayuda.
>
> "Mauricio Pulla" wrote in message
> news:
>> Hola.
>>
>> Tengo la siguiente tabla de Itemes.
>>
>> Item
>> iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int,
>> iParent
>> Int
>>
>> iItemId cItemId cDescripcion iGrupo iParent
>> 1 01 Grupo 1 1
>> 0
>> 2 02 Grupo 2 1
>> 0
>> 3 01 Grupo 3 1
>> 0
>> 4 0101 SubGrupo 0101 1 1
>> 5 0102 SubGrupo 0102 1 1
>> 6 01010001 Item 01010001 0 4
>> 7 010201 SubGrupo 010201 1 4
>> 8 0102010001 Item 010201 0 7
Respuesta Responder a este mensaje
#4 Javier Loria
11/04/2007 - 01:11 | Informe spam
Hola Mauricio:
Con gusto. La solucion estatica seria construir una serie de UNION ALL
que navegan a cada uno de los hijos de los hijos. El codigo con 4 niveles
seria:
==-- 1er Nivel
SELECT *
FROM Item AS I1
WHERE iItemId = 7
UNION ALL
SELECT I2.*
FROM Item AS I1
JOIN Item AS I2
ON I1.iParent=I2.iItemId
WHERE I1.iItemId = 7
UNION ALL
SELECT I3.*
FROM Item AS I1
JOIN Item AS I2
ON I1.iParent=I2.iItemId
JOIN Item AS I3
ON I2.iParent=I3.iItemId
WHERE I1.iItemId = 7
UNION ALL
SELECT I4.*
FROM Item AS I1
JOIN Item AS I2
ON I1.iParent=I2.iItemId
JOIN Item AS I3
ON I2.iParent=I3.iItemId
JOIN Item AS I4
ON I3.iParent=I4.iItemId
WHERE I1.iItemId = 7
== Se podria hace un codigo equivalente, pero hacia "arriba", cambiando la
condicio del ON y reemplazando Ix.IParent=Ix+1.iItemID por su "inverso"
Ix.iItemID=Ix+1.iParent.
Pero este codigo aunque facil de hacer debe tener un numero conocido de
niveles, personalmente lo he usado hasta con 15 niveles :(
El codigo dinamico algo como:
ÞCLARE @Items TABLE (
iItemId INT PRIMARY KEY NOT NULL
)
DECLARE @NumFilas INT

INSERT @Items
VALUES (7)
SET @NumFilas=0;

WHILE (1=1)
BEGIN
SELECT @NumFilas=COUNT(*) FROM @Items
INSERT @Items
SELECT E.iItemId
FROM Items AS I
JOIN @Items AS J
ON I.iParent=J.iItemId
LEFT JOIN @Items AS K
ON I.iItemId=K.iItemId
WHERE K.iItemId IS NULL
IF @NumFilas=(SELECT COUNT(*) FROM @Items)
BEGIN
BREAK;
END
END
SELECT * FROM @Items
= Luego si quieres puedes ponerlo en una función.
Saludos,


Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Mauricio Pulla" wrote in message
news:
Hola Javier.

Utilizo Sql 2000, se me hace dificil actualizarme a Sql 2005.

En todo caso te agradeceria mucho me ilumines un poco, para poder comenzar
a dar solucion a este problemilla.
Donde puedo leer sobre CTE.

Saludos cordiales,
Mauricio Pulla.
Cuenca-Ecuador.

"Javier Loria" escribió en el mensaje
news:
Hola:
Si usas SQL 2005 el problema se puede resolver de forma sencilla una
CTE recursiva.
Si usas SQL 2000 es un poco mas complejo y sobre todo con un desempeño
mucho mas pobre.
Que version usas?

Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Mauricio Pulla" wrote in message
news:
Hola.

Tengo la siguiente tabla de Itemes.

Item
iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int,
iParent
Int

iItemId cItemId cDescripcion iGrupo iParent
1 01 Grupo 1 1
0
2 02 Grupo 2 1
0
3 01 Grupo 3 1
0
4 0101 SubGrupo 0101 1 1
5 0102 SubGrupo 0102 1 1
6 01010001 Item 01010001 0 4
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11
13 01010002 Item 01010002 0 4
14 01010003 Item 01010003 0 4
15 01010004 Item 01010004 0 4
16 01010005 Item 01010005 0 4
17 0102010102 Item 0102010102 0 11

Necesito crear un sql que muestre por ejemplo el registro No.:7 y todos
los
resgistro que se relacionan de forma directa e indirecta con el:

iItemId cItemId cDescripcion
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11

17 0102010102 Item 0102010102 0 11

Seria muy facil:
Select * From Item Where substring(cItemId, 1, 4) = '010201'
Si es que la codificación seria automatica, si la codificacion se la da
manualmente o por codigo de barras ya no seria factible este sql.

Otro Sql seria
Select * From Item Where iItemId = 7
Union
Select * From Item Where iParent = 7

Pero solo traeria:

iItemId cItemId cDescripcion iGrupo iParent
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7

y los restantes registros tienen como iParent al registro 11 que depende
del
regsitro 7
iItemId cItemId cDescripcion iGrupo iParent
12 0102010101 Item 0102010101 0 11
17 0102010102 Item 0102010102 0 11

El problema es algo complejo ya que el usuario puede crear los niveles
que
creyera conveniente, y cItemId puede tener codigo de barras o caracteres
que
no tengan nada que ver con el registro padre.

En todo caso espero su ayuda...

Saludos cordiales.
Mauricio Pulla
Cuenca-Ecuador










Respuesta Responder a este mensaje
#5 Alejandro Mesa
11/04/2007 - 16:10 | Informe spam
Mauricio Pulla,

Chequea el topico "Expanding Hierarchies" en los BOL.

Expanding Hierarchies
http://msdn2.microsoft.com/en-us/library/aa172799(sql.80).aspx

How to show expanding hierarchies by using SQL Server
http://support.microsoft.com/kb/248915

Como ya sabes, no es posible usar recursividad en SQL Server 2000 (no si el
# de niveles es mayor a 32) y por lo tanto se hace muy engorroso trabajar con
este tipo de representacion de jerarquias (Adjacency List). Te recomiendo que
le heches un vistazo a las otras formas que hay de representar jerarquias
como son "Materialized Path", "Nested Sets" y "Nested Intervals".

Materialized Path

Maintaining Hierarchies
http://www.sqlmag.com/articles/index.cfm?articleidˆ26&

Manipulating Hierarchies with UDFs
http://www.sqlmag.com/articles/index.cfm?articleid123&

Inside Microsoft SQL Server 2005: T-SQL Querying
Chapter 9 - Graphs, Trees, Hierarchies, and Recursive Queries
http://www.amazon.com/Inside-Micros...0735623139

Nested Sets
http://www.intelligententerprise.co..._requestid66295

Nested Intervals
http://www.dbazine.com/oracle/or-ar...tropashko4

Joe Celko's Trees and Hierarchies in SQL for Smartie
http://www.amazon.com/Hierarchies-S...ks&qid76300340&sr=1-1

SQL Design Patterns
The Expert Guide to SQL Programming
http://www.rampant-books.com/book_2...styles.htm


AMB

"Mauricio Pulla" wrote:

Hola.

Tengo la siguiente tabla de Itemes.

Item
iItemId Int, cItemId Char(15), cDescripcion VarChar(80), iGrupo Int, iParent
Int

iItemId cItemId cDescripcion iGrupo iParent
1 01 Grupo 1 1
0
2 02 Grupo 2 1
0
3 01 Grupo 3 1
0
4 0101 SubGrupo 0101 1 1
5 0102 SubGrupo 0102 1 1
6 01010001 Item 01010001 0 4
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11
13 01010002 Item 01010002 0 4
14 01010003 Item 01010003 0 4
15 01010004 Item 01010004 0 4
16 01010005 Item 01010005 0 4
17 0102010102 Item 0102010102 0 11

Necesito crear un sql que muestre por ejemplo el registro No.:7 y todos los
resgistro que se relacionan de forma directa e indirecta con el:

iItemId cItemId cDescripcion
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7
12 0102010101 Item 0102010101 0 11

17 0102010102 Item 0102010102 0 11

Seria muy facil:
Select * From Item Where substring(cItemId, 1, 4) = '010201'
Si es que la codificación seria automatica, si la codificacion se la da
manualmente o por codigo de barras ya no seria factible este sql.

Otro Sql seria
Select * From Item Where iItemId = 7
Union
Select * From Item Where iParent = 7

Pero solo traeria:

iItemId cItemId cDescripcion iGrupo iParent
7 010201 SubGrupo 010201 1 4
8 0102010001 Item 010201 0 7
9 0102010002 Item 010202 0 7
10 0102010003 Item 010203 0 7
11 01020101 Grupo 01020101 1 7

y los restantes registros tienen como iParent al registro 11 que depende del
regsitro 7
iItemId cItemId cDescripcion iGrupo iParent
12 0102010101 Item 0102010101 0 11
17 0102010102 Item 0102010102 0 11

El problema es algo complejo ya que el usuario puede crear los niveles que
creyera conveniente, y cItemId puede tener codigo de barras o caracteres que
no tengan nada que ver con el registro padre.

En todo caso espero su ayuda...

Saludos cordiales.
Mauricio Pulla
Cuenca-Ecuador




Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida