Você está na página 1de 20

Utilizando selects hierárquicos. Relação pai-filho na mesma tabela.

Enviado por Cesar Inacio Martins em ter, 29/09/2009 - 17:02

http://www.imartins.com.br/informix/artigos/utilizando-selects-hierarquicos-
relacao-pai-filho-mesma-tabela

Selects hierárquicos são utilizados para tabelas que possuem relacionamento de pai-
filho com ela mesma.
Com elas é possível reescrever um SELECT de modo muito simples, fácil
entendimento e ótima performance. São muito uteis em relacionamento de hierarquia
de setores, empregados, produtos, contabilidade e etc.

Este recurso foi incluído na versão 11.50 xC5, com uma nova sintaxe o comando
SELECT permite uma escrita fácil para este tipo de relacionamento, e para funcionar é
necessário apenas que a tabela seja estruturada de maneira que cada registro tenha
um campo para o relacionamento com o seu item de hierarquia superior.
A sintaxe utilizada é exatamente igual a utilizada pelo Oracle.

Recursos - Vantagens / Desvantagens

Por ser um recurso novo este tipo de select ainda está um pouco limitado, a que mais
você irá sentir é a impossibilidade de realizar um join com outra tabela, por exemplo,
se você precisar buscar uma descrição de uma select hierárquica em outra tabela não
será possível, o que você terá que fazer é gerar o resultado em uma tabela temporária
e então relaciona-la com as demais tabelas.
Outra limitação que irá fazer diferença para quem possui uma grande massa de dados
é impossibilidade de utilizar recursos de paralelismo, o que não é suportado com este
tipo de query.
O filtro da clausula WHERE é realizado após o relacionamento de hierarquia ter sido
realizado. Isto pode parecer uma desvantagem onde você irá pensar que terá
problemas para grande massas de dados, mas não é 100% verdade pois é permitido
realizar filtros no relacionamento de hierarquia. Colocarei exemplos mais abaixo.

As vantagens são inúmeras, onde começamos com a escrita extremamente


simplificada da query , também temos inclusão de funções/operadores que permite
que você filtre ou exiba dados da hierarquia de modo muito fácil e gerando melhor
visualização do seu dado.

Nestas funções/operadores é permitido:

 Exibir o nível de hierarquia que um registro está com relação ao registro pai-
raiz (root)
 Identificar registros que são os últimos da hierárquica, ou seja, que não
possuem filhos (registros leaf)
 Exibir um path completo de cada nível utilizando um separador. Igual a que
vemos quando entramos em diretórios: /usr/local/bin.
 Exbir e tratar registros que geram um loop na hierarquia
 Ordenar por um campo da select, respeitando a hierarquia dos dados.

Sintaxe e comandos

A sintaxe básica é:

SELECT ... [, CONNECT_BY_ISLEAF] [, CONNECT_BY_ISCYCLE] [,


CONNECT_BY_ROOT campo]

[, SYS_CONNECT_BY_PATH()] [, LEVEL]

FROM ...

WHERE ...

[ START WITH condição ]

CONNECT BY [NOCYCLE] PRIOR condição

[ ORDER SIBLINGS BY ...]

Onde os parâmetros descrito entre colchetes são opcionais:

 START WITH: Define qual registro será o inicio da busca pela hierarquia.
Este parâmetro não é obrigatório mas muito útil. Se você não informa-lo o
select irá processar a hierarquia de todos os registros encontrados.
 PRIOR: Utilizado apenas na clausula CONNECT BY, faz o relacionamento
entre os níveis.
Deve-se informar este operador sempre antes de um campo que seja do nível
anterior (superior, do ponto de vista do select). Pode utilizar o operador mais de
uma vez para fazer filtros.
 NOCYCLE: Pode ocorrer situações onde o relacionamento gere um loop o que
poderia gerar um SELECT infinito. O banco detecta estas situações e gera o
erro -26079 quando ocorre. Para evitar este erro deve-se utilizar este operador
e então o retorno do select irá finalizar automaticamente no ultimo item antes
de reiniciar o loop.
 LEVEL: Exibe o nível do registro dentro da hierarquia, baseado na hierarquia
retornada pelo select.
Este operador também pode ser utilizado na clausula CONNECT para filtros.
 CONNECT_BY_ISLEAF: Retorna 1 (numero um) se o registro é um leaf, ou
seja, se é o ultimo registro da hierarquia e não possui filhos.
Este comando não pode ser utilizado em nenhuma clausula de condição
(where, connect, start).
 CONNECT_BY_ISCYCLE: Pode ser utilizado apenas quando o operador
NOCYCLE foi especificado. Retorna 1 (numero um) quando o registro é o
ultimo da hierarquia e possui o relacionamento que irá iniciar o loop. Este
comando não pode ser utilizado em nenhuma clausula de condição (where,
connect, start).
 CONNECT_BY_ROOT [campo]: Exibe um campo do registro pai/root na
hierarquia do registro exibido. Este comando não pode ser utilizado em
nenhuma clausula de condição (where, connect, start).
 SYS_CONNECT_BY_PATH(campo, separador): Retorna uma string
(LVARCHAR(4000)) com o path de toda hierarquia utilizado o campo e
separador especificado. Este comando não pode ser utilizado em nenhuma
clausula de condição (where, connect, start).
 ORDER SIBLINGS BY: Este operador só pode ser utilizado com o CONNECT
BY. Ele reordena apenas os itens que fazem parte do do mesmo nível na
hierarquia.

Clasula WHERE

A clausula WHERE só é aplicada na query após os relacionamentos hierárquicos


terem sido feitos, portanto não considere ela como seu filtro principal. Para filtros
primários e básicos utilize a clausula CONNECT BY.
Abaixo segue a ordem que o Informix processa internamente os dados.
Copiado do Manual IDS 11.50 xC5 - SQL Syntax, pagina 2-583

The clauses of a SELECT statement that includes the Hierarchical clause are
processed in the following sequence:
1. FROM clause (for only a single table object in the current database)
2. Hierarchical clause
3. WHERE clause (without join predicates)
4. GROUP BY clause
5. HAVING clause
6. Projection clause
7. ORDER BY clause
Exemplos

# Crio uma estrutura de empresas onde monto relações hierárquicas entre

# elas, identificando o tipo de cada uma e quem é a empresa pai

# através do campo cd_emp_pai.

create table empresas (

cd_emp int

, desc varchar(16)

, tipo char(2) check (tipo in ("F","QG","M","P"))

, cd_emp_pai int );

Table created.
alter table empresas add constraint primary key (cd_emp) constraint pk_emp;

Table altered.

insert into empresas values ( 1, "Matriz", "M" , null );

insert into empresas values ( 2, "QG_SP", "QG" , 1 );

insert into empresas values ( 3, "Filial_SP1", "F" , 2 );

insert into empresas values ( 4, "Filial_SP2", "F" , 2 );

insert into empresas values ( 5, "Filial_SP3", "F" , 2 );

insert into empresas values ( 6, "Posto_Avancado 1", "P" , 3 );

insert into empresas values ( 7, "Posto_Avancado 2", "P" , 3 );

insert into empresas values ( 8, "Posto_Avancado 3", "P" , 4 );

insert into empresas values ( 9, "QG_RJ", "QG" , 1 );

insert into empresas values (10, "Filial_RJ1", "F" , 9 );

insert into empresas values (11, "Filial_RJ2", "F" , 9 );

insert into empresas values (12, "Posto_Avancado 4", "P" , 11 );

# Seleciono toda hierarquia de baixo p/ cima, do "Posto Avancado 4"

# até a matriz

SELECT * FROM empresas

START WITH cd_emp = (select max(cd_emp) from empresas)

CONNECT BY PRIOR cd_emp_pai = cd_emp;

cd_emp desc tipo cd_emp_pai

12 Posto_Avancado 4 P 11

11 Filial_RJ2 F 9

9 QG_RJ QG 1

1 Matriz M

4 row(s) retrieved.
# Executo no sentido inverso, de cima p/ baixo, ou seja,

# da Matriz até o ultimo item.

# Repare que mudo de o operador PRIOR para o campo cd_emp

# que indica então que este campo é o do registro superior na hierarquia

SELECT * FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp ;

cd_emp desc tipo cd_emp_pai

1 Matriz M

9 QG_RJ QG 1

11 Filial_RJ2 F 9

12 Posto_Avancado 4 P 11

10 Filial_RJ1 F 9

2 QG_SP QG 1

5 Filial_SP3 F 2

4 Filial_SP2 F 2

8 Posto_Avancado 3 P 4

3 Filial_SP1 F 2

7 Posto_Avancado 2 P 3

6 Posto_Avancado 1 P 3

12 row(s) retrieved.

# Altero código da Matriz de modo que criamos um loop

# eterno ao utilizar o CONNECT BY, desta maneira

# o banco detecta o loop e gera o erro:

# 26079: CONNECT BY query resulted in a loop/cycle.


UPDATE empresas SET cd_emp_pai = 12 where cd_emp = 1 ;

1 row(s) updated.

SELECT * FROM empresas

START WITH cd_emp = (select max(cd_emp) from empresas)

CONNECT BY PRIOR cd_emp_pai = cd_emp ;

cd_emp desc tipo cd_emp_pai

12 Posto_Avancado 4 P 11

11 Filial_RJ2 F 9

9 QG_RJ QG 1

26079: CONNECT BY query resulted in a loop/cycle.

Error in line 39

Near character position 35

# Para evitar este problema basta utilizar o comando

# NOCYCLE que indica para não realizar estas querys recursivas.

SELECT *

, CONNECT_BY_ISCYCLE

FROM empresas

START WITH cd_emp = (select max(cd_emp) from empresas)

CONNECT BY NOCYCLE PRIOR cd_emp_pai = cd_emp ;

cd_emp desc tipo cd_emp_pai connect_by_iscycle

12 Posto_Avancado 4 P 11 0

11 Filial_RJ2 F 9 0

9 QG_RJ QG 1 0

1 Matriz M 12 1

4 row(s) retrieved.
# Desfaço o loop

UPDATE empresas SET cd_emp_pai = null where cd_emp = 1 ;

1 row(s) updated.

# Demonstração dos comandos CONNECT_BY_ISLEAF e LEVEL

# Observe que o resultado destes comandos são referentes

# ao todo conteúdo retornado, portanto não tem relação com

# situação dos dados na tabela.

SELECT *, CONNECT_BY_ISLEAF leaf, LEVEL

FROM empresas

START WITH cd_emp = 6

CONNECT BY PRIOR cd_emp_pai = cd_emp;

cd_emp desc tipo cd_emp_pai leaf level

6 Posto_Avancado 1 P 3 0 1

3 Filial_SP1 F 2 0 2

2 QG_SP QG 1 0 3

1 Matriz M 1 4

4 row(s) retrieved.

SELECT *, CONNECT_BY_ISLEAF leaf, LEVEL

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp ;

cd_emp desc tipo cd_emp_pai leaf level

1 Matriz M 0 1

9 QG_RJ QG 1 0 2

11 Filial_RJ2 F 9 0 3
12 Posto_Avancado 4 P 11 1 4

10 Filial_RJ1 F 9 1 3

2 QG_SP QG 1 0 2

5 Filial_SP3 F 2 1 3

4 Filial_SP2 F 2 0 3

8 Posto_Avancado 3 P 4 1 4

3 Filial_SP1 F 2 0 3

7 Posto_Avancado 2 P 3 1 4

6 Posto_Avancado 1 P 3 1 4

12 row(s) retrieved.

# Aqui podemos ver a utilização do operador LEVEL na

# parte de filtro do CONNECT

SELECT *, CONNECT_BY_ISLEAF leaf, LEVEL

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp

AND LEVEL <=3 ;

cd_emp desc tipo cd_emp_pai leaf level

1 Matriz M 0 1

9 QG_RJ QG 1 0 2

11 Filial_RJ2 F 9 1 3

10 Filial_RJ1 F 9 1 3

2 QG_SP QG 1 0 2

5 Filial_SP3 F 2 1 3

4 Filial_SP2 F 2 1 3

3 Filial_SP1 F 2 1 3

8 row(s) retrieved.
# Demonstração do comando CONNECT_BY_ROOT e do filtro WHERE

# Observe que o nivel (campo LEVEL) não considera o registro

# filtrado pela clausula WHERE

SELECT *

, CONNECT_BY_ROOT desc as root_desc

, LEVEL

FROM empresas

WHERE tipo != "M"

START WITH tipo = "F"

CONNECT BY cd_emp_pai = PRIOR cd_emp ;

cd_emp desc tipo cd_emp_pai root_desc


level

11 Filial_RJ2 F 9 Filial_RJ2
1

12 Posto_Avancado 4 P 11 Filial_RJ2
2

10 Filial_RJ1 F 9 Filial_RJ1
1

5 Filial_SP3 F 2 Filial_SP3
1

4 Filial_SP2 F 2 Filial_SP2
1

8 Posto_Avancado 3 P 4 Filial_SP2
2

3 Filial_SP1 F 2 Filial_SP1
1

7 Posto_Avancado 2 P 3 Filial_SP1
2

6 Posto_Avancado 1 P 3 Filial_SP1
2

9 row(s) retrieved.

# Demonstração do comando SYS_CONNECT_BY_PATH.


# Neste exemplo utilizo o CAST apenas para diminuir o tamanho da

# string para que retorne todos os campos em uma unica linha.

SELECT cd_emp, desc, tipo

, cast(SYS_CONNECT_BY_PATH(desc, "/") as char(42)) as path

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp ;

cd_emp desc tipo path

1 Matriz M /Matriz

9 QG_RJ QG /Matriz/QG_RJ

11 Filial_RJ2 F /Matriz/QG_RJ/Filial_RJ2

12 Posto_Avancado 4 P
/Matriz/QG_RJ/Filial_RJ2/Posto_Avancado 4

10 Filial_RJ1 F /Matriz/QG_RJ/Filial_RJ1

2 QG_SP QG /Matriz/QG_SP

5 Filial_SP3 F /Matriz/QG_SP/Filial_SP3

4 Filial_SP2 F /Matriz/QG_SP/Filial_SP2

8 Posto_Avancado 3 P
/Matriz/QG_SP/Filial_SP2/Posto_Avancado 3

3 Filial_SP1 F /Matriz/QG_SP/Filial_SP1

7 Posto_Avancado 2 P
/Matriz/QG_SP/Filial_SP1/Posto_Avancado 2

6 Posto_Avancado 1 P
/Matriz/QG_SP/Filial_SP1/Posto_Avancado 1

12 row(s) retrieved.

# Abaixo segue algumas demonstrações de filtros no CONNECT

# e WHERE

SELECT *, LEVEL

FROM empresas

START WITH tipo = "M"


CONNECT BY cd_emp_pai = PRIOR cd_emp

AND tipo IN ("QG","F") ;

cd_emp desc tipo cd_emp_pai level

1 Matriz M 1

9 QG_RJ QG 1 2

11 Filial_RJ2 F 9 3

10 Filial_RJ1 F 9 3

2 QG_SP QG 1 2

5 Filial_SP3 F 2 3

4 Filial_SP2 F 2 3

3 Filial_SP1 F 2 3

8 row(s) retrieved.

SELECT *, LEVEL

FROM empresas

WHERE LEVEL != 2

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp

AND tipo IN ("QG","F") ;

cd_emp desc tipo cd_emp_pai level

1 Matriz M 1

11 Filial_RJ2 F 9 3

10 Filial_RJ1 F 9 3

5 Filial_SP3 F 2 3

4 Filial_SP2 F 2 3

3 Filial_SP1 F 2 3

6 row(s) retrieved.
SELECT *, LEVEL

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp

AND ( ( LEVEL = 2 and tipo = "QG" ) OR

( LEVEL = 3 and tipo = "F" )) ;

cd_emp desc tipo cd_emp_pai level

1 Matriz M 1

9 QG_RJ QG 1 2

11 Filial_RJ2 F 9 3

10 Filial_RJ1 F 9 3

2 QG_SP QG 1 2

5 Filial_SP3 F 2 3

4 Filial_SP2 F 2 3

3 Filial_SP1 F 2 3

8 row(s) retrieved.

# Exemplo de registros sendo ordenado pelo campo DESC

# através do comando ORDER SIBLINGS BY

SELECT *, LEVEL

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp

ORDER SIBLINGS BY desc ;

cd_emp desc tipo cd_emp_pai level

1 Matriz M 1

9 QG_RJ QG 1 2

10 Filial_RJ1 F 9 3
11 Filial_RJ2 F 9 3

12 Posto_Avancado 4 P 11 4

2 QG_SP QG 1 2

3 Filial_SP1 F 2 3

6 Posto_Avancado 1 P 3 4

7 Posto_Avancado 2 P 3 4

4 Filial_SP2 F 2 3

8 Posto_Avancado 3 P 4 4

5 Filial_SP3 F 2 3

12 row(s) retrieved.

Database closed.

Debugando
Para identificar como um select hierarquico está sendo utilizado, utilize o
comando SET EXPLAIN, através deste comando é possível ver e entender como o
Informix faz os relacionamentos internamente e aplica os filtros.
Exemplo de um output do SET EXPLAIN:

QUERY: (OPTIMIZATION TIMESTAMP: 09-29-2009 15:49:43)

------

SELECT *

, CONNECT_BY_ROOT desc as root_desc

, LEVEL

FROM empresas

WHERE tipo != "M"

START WITH tipo = "F"

CONNECT BY cd_emp_pai = PRIOR cd_emp

Connect by Query Rewrite:

---------------------------
select x0.cd_emp ,x0.desc ,x0.tipo ,x0.cd_emp_pai
,x0.dtab_22679_439_desc ,x0.level

from (select x1.cd_emp ,x1.desc ,x1.tipo ,x1.cd_emp_pai ,x1.cd_emp ,1


,1 ,0 ,x1.desc

from "informix".empresas x1 where (x1.tipo = 'F' ) union all select


x2.cd_emp ,x2.desc ,x2.tipo

,x2.cd_emp_pai ,x2.cd_emp ,(level + 1 ) ::integer ,connect_by_isleaf


,dtab_22679_439_stkcol

,dtab_22679_439_desc from "informix".empresas x2


,"informix".dtab_22679_439 x0

where (x2.cd_emp_pai = dtab_22679_439_p_cd_emp ) )

x0(cd_emp,desc,tipo,cd_emp_pai,dtab_22679_439_p_cd_emp,level,connect_b
y_isleaf,dtab_22679_439_stkcol

,dtab_22679_439_desc)where (x0.tipo != 'M' )

Estimated Cost: 1

Estimated # of Rows Returned: 2

1) informix.dtab_22679_439: COLLECTION SCAN

Subquery:

---------

Estimated Cost: 8

Estimated # of Rows Returned: 2

1) informix.empresas: SEQUENTIAL SCAN

Filters: informix.empresas.tipo = 'F'

Subquery:

---------

Estimated Cost: 5

Estimated # of Rows Returned: 1


1) informix.dtab_22679_439: SEQUENTIAL SCAN

2) informix.empresas: SEQUENTIAL SCAN

DYNAMIC HASH JOIN (Build Outer)

Dynamic Hash Filters: informix.empresas.cd_emp_pai =


informix.dtab_22679_439.dtab_22679_439_p_cd_emp

Filters: informix.dtab_22679_439.tipo != 'M'

Query statistics:

-----------------

Table map :

----------------------------

Internal name Table name

----------------------------

t1 dtab_22679_439

type table rows_prod time

-----------------------------------

clscan t1 9 00:00.00

Média:

.9
Média: 4.9 (10 votos)
Cancelar a avaliação
Sua avaliação:

ancelar a avaliação

oor

kay

om

reat

wesome
Sua avaliação: Nenhum

 32351 leituras

Tags:

 sql

Cesar, obrigado pelo pronto


Enviado por Odie em sab, 15/09/2012 - 23:47.
Cesar, obrigado pelo pronto atendimento. Veja o problema neste site: http://www.adp-
gmbh.ch/blog/2009/09/29.php Só que a solução é muito complexa e envolve criar uma série
de objetos específicos para a solução. O problema que citei é similar.

 responder

Possibilidade de solução
Enviado por Cesar Inacio Martins em ter, 18/09/2012 - 08:42.

Odie,

Verifiquei o link e pensei um pouco aqui sobre a questão.

O jeito mais "facil" que vi para a solução é trabalhar com o "START WITH" , porém o nivel

que vc quer realizar o sum, vc precisa pegar antecipadamente, via tabela temporária ou

especificando no select :

Resultado final :

desc1 cd_emp tipo cd_emp_pai valor level

Matriz 1 M 3 1

QG_RJ 9 QG 1 10 2

Filial 11 F 9 3 3

Post 12 P 11 4 4
Filial 10 F 9 11 3

QG_SP 2 QG 1 4 2

Filial 5 F 2 1 3

Filial 4 F 2 2 3

Post 8 P 4 1 4

Filial 3 F 2 1 3

Post 7 P 3 2 4

Post 6 P 3 3 4

-- Exemplo usando tabela temporaria

desc valor

QG_RJ 28

QG_SP 14

-- Exemplo especificando os valores manualmente.

desc valor

QG_RJ 28

QG_SP 14

COMANDOS SQLs UTILIZADOS

drop table if exists empresas;

create table empresas ( cd_emp int , desc varchar(16) , tipo char(2)


check (tipo in ("F","QG","M","P")) , cd_emp_pai int , valor int );

alter table empresas add constraint primary key (cd_emp) constraint


pk_emp;

insert into empresas values ( 1, "Matriz", "M" , null ,3);

insert into empresas values ( 2, "QG_SP", "QG" , 1 ,4);

insert into empresas values ( 3, "Filial_SP1", "F" , 2 ,1);


insert into empresas values ( 4, "Filial_SP2", "F" , 2 ,2);

insert into empresas values ( 5, "Filial_SP3", "F" , 2 ,1);

insert into empresas values ( 6, "Posto_Avancado 1", "P" , 3 ,3);

insert into empresas values ( 7, "Posto_Avancado 2", "P" , 3 ,2);

insert into empresas values ( 8, "Posto_Avancado 3", "P" , 4 ,1);

insert into empresas values ( 9, "QG_RJ", "QG" , 1 ,10);

insert into empresas values (10, "Filial_RJ1", "F" , 9 ,11);

insert into empresas values (11, "Filial_RJ2", "F" , 9 ,3);

insert into empresas values (12, "Posto_Avancado 4", "P" , 11 ,4 );

SELECT (lpad ('', (level-1)*2, ' ')||desc)::char(10) as desc1

, cd_emp, tipo , cd_emp_pai, valor,LEVEL

FROM empresas

START WITH tipo = "M"

CONNECT BY cd_emp_pai = PRIOR cd_emp ;

-- cria temporaria para filtro

drop table if exists tp01;

SELECT tipo FROM empresas

where level = 2

START WITH tipo = 'M'

CONNECT BY cd_emp_pai = PRIOR cd_emp

into temp tp01 with no log

-- versao usando temporaria

SELECT CONNECT_BY_ROOT desc , sum(valor) as valor

FROM empresas

START WITH tipo in (select tipo from tp01)

CONNECT BY cd_emp_pai = PRIOR cd_emp


group by 1

-- versao sem temporaria

SELECT CONNECT_BY_ROOT desc , sum(valor) as valor

FROM empresas

START WITH tipo like "QG%"

CONNECT BY cd_emp_pai = PRIOR cd_emp

group by 1

Espero que isso ajude.

 responder

Cesar, novamente obrigado por


Enviado por Odie em ter, 18/09/2012 - 21:12.
Cesar, novamente obrigado por responder tão rápido. Sua solução é interessante, não avaliei
a performance, mas utilizei uma solução sem a necessidade de tabelas temporárias. Veja o
link do Ask
Tom: http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:30609... É
uma alternativa bastante "clean" e bem fácil de adaptar. Atribuí zero para os país e efetuei o
somatório. Funcionou legal e bastante rápido. Mas o problema agora é outro. Existem
atributos específicos da tabela de receita que preciso levar para toda a árvore, mas como só
se relaciona com o último nível da natureza, os valores são perdidos. Na verdade eu quero
que outros atributos da receita que está relacionada ao último nó seja repetido nos níveis
acima. Com o valor consegui usando o exemplo que trabalha com a função sum. Mas como
fazer o mesmo com campos tipo data, chaves secundárias e outros tipos, que não devem
sofrer modificações? abraços []´s

 responder

Somatório nos pais quando valor está no filho (em outra tabela)
Enviado por Odie em sab, 15/09/2012 - 16:00.
Realmente foi o mais esclarecedor dos post sobre o assunto. É legal quando se expõe os prós
e os contras. Agora, indo direto ao meu problema, veja se pode ajudar: Tenho uma tabela
de natureza da receita que tem a estrutura hierarquizada. Tenho também uma tabela de
receita que contem os valores das naturezas de receita no último nível. Como posso fazer
uma consulta que possa gerar os valores somados de todos os níveis?

 responder

RE: Somatório...
Enviado por Cesar Inacio Martins em sab, 15/09/2012 - 22:32.

Ola Odie ,
Olha, se entendi bem o que vc precisa, seria utilizar um group by + sum .

Estou certo?

Se for, acredito que o apenas a especificação destes itens já seria o suficiente.

Mas para ter certeza, seria legal vc postar aqui um mini exemplo (criação de tabela, inclusão

de dado e o resultado que vc gostaria de obter). E ai vejo o que consigo lhe ajudar.

Abraço

Cesar

 responder

Retornar o nó e o seu ROOT


Enviado por Gustavo em qui, 31/05/2012 - 08:04.
Muito bom o artigo. Eu tenho uma necessidade que não sei se é possível. Preciso trazer a
partir de qualquer nó, o seu ROOT. No seu primeiro exemplo se eu passar 12 quero que
retorne 1 que é o ROOT que me refiro, seria sempre pegar o nível 1 de qualquer nó que
fosse passado. Ainda no primeiro exemplo se eu passar o 11 também quero que retorno o 1.
Me fiz entender ? Grato.

 responder

RE: Retornar o nó e o seu ROOT


Enviado por Cesar Inacio Martins em qui, 31/05/2012 - 08:54.

Olá Gustavo,

Não tenho certeza se entendi 100%.

Mas pelo o que entendi, vc apenas precisa usar o CONNECT_BY_ROOT , tem um exemplo

com ele na pagina.