Dúvida difícil de SQL.
Tenho duas tabelas como descrevo abaixo:
tab1 => iCodPai, iCodComponemte
tab2 => iCod, iTipo
Para 1 iPai existe vários iComponentes com iTipo que pode ser P ou C. Para saber todos os iComponentes de um iPai, fiz a seguinte query:
select E.iCodPai, E.iCodComponente, I.iTipo
from tab1 E, tab2 I
where E.iCodPai = ´4902000150A´ AND
E.iCodComponente = I.iCod
Result. : 4902000150A AAAAAA C
4902000150A BBBBBBB C
4902000150A CCCCCC P
4902000150A DDDDDD C
4902000150A EEEEEEE C
4902000150A FFFFFFF P
4902000150A GGGGG C
4902000150A HHHHHH P
Qdo o tipo for P, implica dizer que existe uma estrutura por baixo desse componente. É como se fizesse a query acima com o iCodPai = (produto que for P). Isso pode ocorrer em até seis níveis.
Como eu faria essa query para desdobrar os produtos até que eles cheguem todos a C?
Obrigado.
tab1 => iCodPai, iCodComponemte
tab2 => iCod, iTipo
Para 1 iPai existe vários iComponentes com iTipo que pode ser P ou C. Para saber todos os iComponentes de um iPai, fiz a seguinte query:
select E.iCodPai, E.iCodComponente, I.iTipo
from tab1 E, tab2 I
where E.iCodPai = ´4902000150A´ AND
E.iCodComponente = I.iCod
Result. : 4902000150A AAAAAA C
4902000150A BBBBBBB C
4902000150A CCCCCC P
4902000150A DDDDDD C
4902000150A EEEEEEE C
4902000150A FFFFFFF P
4902000150A GGGGG C
4902000150A HHHHHH P
Qdo o tipo for P, implica dizer que existe uma estrutura por baixo desse componente. É como se fizesse a query acima com o iCodPai = (produto que for P). Isso pode ocorrer em até seis níveis.
Como eu faria essa query para desdobrar os produtos até que eles cheguem todos a C?
Obrigado.
Julianomc
Curtidas 0
Respostas
Julianomc
12/08/2003
Será que alguém pode me ajuda?! Estou parado nisto e nõa consigo solucionar....
GOSTEI 0
Torres Delphi
12/08/2003
Se eu entendi direito, eh so incluir a clausula ´AND I.itipo = ´P´
GOSTEI 0
Julianomc
12/08/2003
Não. O que preciso é do qdo o iTipo for P, quer dizer que existe uma estrutura também debaixo dele, ou seja, agora o iComponente passa a ser iPai na verificação. Tenho que descer todos os níveis até o último ser C. E existe no máximo 6 níveis.
GOSTEI 0
Motta
12/08/2003
sql ansi não resolve isto em uma query, alguns bancos tem extenções nativas que resolvem isto.
Oracle tem a connect by.
Não sei para os demais.
Oracle tem a connect by.
Não sei para os demais.
GOSTEI 0
Julianomc
12/08/2003
Você sabe pelo informix?
GOSTEI 0
Julianomc
12/08/2003
Nossa Galera, será que é tão difícil mesmo?! Se alguém puder me ajudar, eu agradeceria muito, só falta eu resolver isso, e não consigo terminar...
GOSTEI 0
Edmar Bittar
12/08/2003
Julianomc:
Achei sua dúvida das mais interessante.
Como não encontrou solução, vou arriscar ajudá-lo.
Ficou extenso. Se ajudar, ou se encontrar a resposta, favor envie-me.
Sua Query:
select E.iCodPai, E.iCodComponente, I.iTipo
from tab1 E, tab2 I
where E.iCodPai = ´4902000150A´ AND
E.iCodComponente = I.iCod
public
procedure NovaQuery(CodPai, Cod: String);
var
Form1 : TForm1;
StrList : TStringList;
procedure TForm1.Create(Sender : TObject);
begin
...
StrList := TStringList.Create;
...
end;
procedure TForm1........
begin
Query1.Close;
.....// Sua Query.
.....
Query1.Open;
Query1.First;
while not Query1.EOF do
begin
if Query1.FieldbyName(iTipo).Value = ´P´ then
NovaQuery(Query1.FieldbyName(E.i´CodPai´).Value , Query1.FieldbyName(´I.iTipo´).Value)
else
StrList.Add(Query1.FieldbyName(E.i´CodPai´).Value + ´ ´ + Query1.FieldbyName(E.´iCodComponente´).Value + ´ ´ + Query1.FieldbyName(´I.iTipo´).Value);
Query1.Next;
end;
...
end;
procedure TForm1.NovaQuery(CodPai, Cod: String);
var
P1, P2: String;
begin
P1:= CodPai;
P2 := Cod;
try
Query.Close;
Query2.Clear;
Query2.Add(´select E.iCodPai, E.iCodComponente, I.iTipo ´);
Query2.Add(´from tab1 E, tab2 I ´);
Query2.Add(´where E.iCodPai = :CodPai AND ´);
Query2.Add(´E.iCodComponente = I.iCod AND´);
Query2.Add(´E.iCodComponente = :Cod);
Query2.ParambyName(´CodPai´).asString := P1;
Query2.ParambyName(´Cod´).asString := P2;
Query2.Open;
Query2.First;
while not Query2.EOF do
begin
if Query1.FieldbyName(I.iTipo).Value = ´P´ then
NovaQuery(Query2.FieldbyName(E.i´CodPai´).Value , Query2.FieldbyName(´I.iTipo´).Value)
else
StrList.Add(Query2.FieldbyName(E.i´CodPai´).Value + ´ ´ + Query2.FieldbyName (E.´iCodComponente´).Value + ´ ´ + Query2.FieldbyName(´I.iTipo´).Value;
Query2.Next;
end;
finally
Query2.Free;
end;
Usando recursividade, talvez resolva.
Achei sua dúvida das mais interessante.
Como não encontrou solução, vou arriscar ajudá-lo.
Ficou extenso. Se ajudar, ou se encontrar a resposta, favor envie-me.
Sua Query:
select E.iCodPai, E.iCodComponente, I.iTipo
from tab1 E, tab2 I
where E.iCodPai = ´4902000150A´ AND
E.iCodComponente = I.iCod
public
procedure NovaQuery(CodPai, Cod: String);
var
Form1 : TForm1;
StrList : TStringList;
procedure TForm1.Create(Sender : TObject);
begin
...
StrList := TStringList.Create;
...
end;
procedure TForm1........
begin
Query1.Close;
.....// Sua Query.
.....
Query1.Open;
Query1.First;
while not Query1.EOF do
begin
if Query1.FieldbyName(iTipo).Value = ´P´ then
NovaQuery(Query1.FieldbyName(E.i´CodPai´).Value , Query1.FieldbyName(´I.iTipo´).Value)
else
StrList.Add(Query1.FieldbyName(E.i´CodPai´).Value + ´ ´ + Query1.FieldbyName(E.´iCodComponente´).Value + ´ ´ + Query1.FieldbyName(´I.iTipo´).Value);
Query1.Next;
end;
...
end;
procedure TForm1.NovaQuery(CodPai, Cod: String);
var
P1, P2: String;
begin
P1:= CodPai;
P2 := Cod;
try
Query.Close;
Query2.Clear;
Query2.Add(´select E.iCodPai, E.iCodComponente, I.iTipo ´);
Query2.Add(´from tab1 E, tab2 I ´);
Query2.Add(´where E.iCodPai = :CodPai AND ´);
Query2.Add(´E.iCodComponente = I.iCod AND´);
Query2.Add(´E.iCodComponente = :Cod);
Query2.ParambyName(´CodPai´).asString := P1;
Query2.ParambyName(´Cod´).asString := P2;
Query2.Open;
Query2.First;
while not Query2.EOF do
begin
if Query1.FieldbyName(I.iTipo).Value = ´P´ then
NovaQuery(Query2.FieldbyName(E.i´CodPai´).Value , Query2.FieldbyName(´I.iTipo´).Value)
else
StrList.Add(Query2.FieldbyName(E.i´CodPai´).Value + ´ ´ + Query2.FieldbyName (E.´iCodComponente´).Value + ´ ´ + Query2.FieldbyName(´I.iTipo´).Value;
Query2.Next;
end;
finally
Query2.Free;
end;
Usando recursividade, talvez resolva.
GOSTEI 0
Motta
12/08/2003
não conheço informix a solução seria montar a recursividade na mão.
acho que a solução passda resolve
acho que a solução passda resolve
GOSTEI 0
Julianomc
12/08/2003
Valeu mesmo.
Vou colocar em prática agora. Qualquer novidade eu te aviso.
Obrigado.
Vou colocar em prática agora. Qualquer novidade eu te aviso.
Obrigado.
GOSTEI 0