SQL com Join para retornar campos correspondentes...
Olá! Tenho duas tabelas com as seguintes estruturas:
Tabela ´PRATOS´
===============
CODIGO INTEGER
DESCRICAO VARCHAR(40)
Tabela ´CARDAPIO´
=================
CODCARDAPIO INTEGER
PRATO1 INTEGER
PRATO2 INTEGER
PRATO3 INTEGER
PRATO4 INTEGER
Eu queria fazer um select na tabela cardapio com algum tipo de join que ao invés dele me retornar os campos inteiros ele me retornasse as descrições dos pratos correspondentes. Exemplo:
Ao invés de:
===============================================
CODCARDAPIO | PRATO1 | PRATO2 | PRATO3 | PRATO4
===============================================
1 | 22 | 33 | 15 | 87
===============================================
Ele me retornasse
===============================================
CODCARDAPIO | PRATO1 | PRATO2 | PRATO3 | PRATO4
===============================================
1 | CHUCHU | CAFÉ | ARROZ | AÇÚCAR
===============================================
Aproveito também para tirar uma outra dúvida. Quais indices,foreign keys eu deveria criar para essas duas tabelas, se é que deveria ter algum entre elas duas. Ah, estou usando Firebird 1.5.
Valeu pela ajuda!
Tabela ´PRATOS´
===============
CODIGO INTEGER
DESCRICAO VARCHAR(40)
Tabela ´CARDAPIO´
=================
CODCARDAPIO INTEGER
PRATO1 INTEGER
PRATO2 INTEGER
PRATO3 INTEGER
PRATO4 INTEGER
Eu queria fazer um select na tabela cardapio com algum tipo de join que ao invés dele me retornar os campos inteiros ele me retornasse as descrições dos pratos correspondentes. Exemplo:
Ao invés de:
===============================================
CODCARDAPIO | PRATO1 | PRATO2 | PRATO3 | PRATO4
===============================================
1 | 22 | 33 | 15 | 87
===============================================
Ele me retornasse
===============================================
CODCARDAPIO | PRATO1 | PRATO2 | PRATO3 | PRATO4
===============================================
1 | CHUCHU | CAFÉ | ARROZ | AÇÚCAR
===============================================
Aproveito também para tirar uma outra dúvida. Quais indices,foreign keys eu deveria criar para essas duas tabelas, se é que deveria ter algum entre elas duas. Ah, estou usando Firebird 1.5.
Valeu pela ajuda!
Delphi32
Curtidas 0
Respostas
Fórum Vini
14/10/2004
Olá,
tente usar esse SQL:
(Não sei se irá funcionar para FB, mas para SQL Server parece funcionar corretamente..)
Espero ter ajudado,
Vinicius;
tente usar esse SQL:
Select C.CodCardapio, P1.Descricao as PRATO1, P2.Descricao as PRATO2, P3.Descricao as PRATO3, P4.Descricao as PRATO4 from Cardapio as C INNER JOIN Pratos as P1 ON (P1.Codigo = C.Prato1) INNER JOIN Pratos as P2 ON (P2.Codigo = C.Prato2) INNER JOIN Pratos as P3 ON (P3.Codigo = C.Prato3) INNER JOIN Pratos as P4 ON (P4.Codigo = C.Prato4)
(Não sei se irá funcionar para FB, mas para SQL Server parece funcionar corretamente..)
Espero ter ajudado,
Vinicius;
GOSTEI 0
Delphi32
14/10/2004
funcionou perfeitamente! muito obrigado mesmo!
GOSTEI 0
Vinicius2k
14/10/2004
Eu faria direferente: não usaria INNER.
Se for possível que um cardápio não tenha os 4 pratos a linha sem correspondecia total não seria considerada.
É importante também perceber a diferença entre as posições (à esquerda e à direita) das tabelas na cláusula ON do join, já que influenciam diretamente no resultado.
Por ultimo, na sintaxe do SQL Server do ´chará´, existem AS para determinar um álias para as tabelas, que não são aceitos no Firebird... vc, provavelmente, os removeu...
Bem... este seria meu código:
E sobre a questão das FKs, elas nunca são estritamente necessárias, vc é quem decide se as quer ou não, mas se quiser, a criação das tabelas seria assim :
T+
Se for possível que um cardápio não tenha os 4 pratos a linha sem correspondecia total não seria considerada.
É importante também perceber a diferença entre as posições (à esquerda e à direita) das tabelas na cláusula ON do join, já que influenciam diretamente no resultado.
Por ultimo, na sintaxe do SQL Server do ´chará´, existem AS para determinar um álias para as tabelas, que não são aceitos no Firebird... vc, provavelmente, os removeu...
Bem... este seria meu código:
select C.CODCARDAPIO, P1.DESCRICAO as PRATO1, P2.DESCRICAO as PRATO2, P3.DESCRICAO as PRATO3, P4.DESCRICAO as PRATO4 from CARDAPIO C left join PRATOS P1 on (C.CODCARDAPIO = P1.CODIGO) left join PRATOS P2 on (C.CODCARDAPIO = P2.CODIGO) left join PRATOS P3 on (C.CODCARDAPIO = P3.CODIGO) left join PRATOS P4 on (C.CODCARDAPIO = P4.CODIGO)
E sobre a questão das FKs, elas nunca são estritamente necessárias, vc é quem decide se as quer ou não, mas se quiser, a criação das tabelas seria assim :
create table PRATOS ( CODIGO INTEGER not null, DESCRICAO VARCHAR(40), constraint PK_PRATOS primary key (CODIGO) ); create table CARDAPIO ( CODCARDAPIO integer not null, PRATO1 integer, PRATO2 integer, PRATO3 integer, PRATO4 integer, constraint PK_CARDAPIO primary key (CODCARDAPIO), constraint FK_CARDAPIO_A foreign key (PRATO1) references PRATOS (CODIGO), constraint FK_CARDAPIO_B foreign key (PRATO2) references PRATOS (CODIGO), constraint FK_CARDAPIO_C foreign key (PRATO3) references PRATOS (CODIGO), constraint FK_CARDAPIO_D foreign key (PRATO4) references PRATOS (CODIGO) );
T+
GOSTEI 0
Fórum Vini
14/10/2004
Eu faria direferente: não usaria INNER.
Se for possível que um cardápio não tenha os 4 pratos a linha sem correspondecia total não seria considerada.
Hum.. eu nunca consegui enfiar na minha cabeça pra que servia o Left join... então é pra isso? :P
Por ultimo, na sintaxe do SQL Server do ´chará´, existem AS para determinar um álias para as tabelas, que não são aceitos no Firebird
Hum.. foi bom saber :wink:
Ae 2K, obrigado pelas correções, vc sabe que eu sou ignorante em BD :roll:
T+,
Vinicius;
GOSTEI 0
Vinicius2k
14/10/2004
Que isso chará? estamos todos no mesmo barco... aprendendo sempre...
E olhando com mais calma vi q postei um código errado tbm... perdão :oops:
O correto seria este :
Fiz comparação dentro do ON pelo CODCARDAPIO... nada haver...
Aqui tem explicação sobre joins de ´quem entende´... :D
http://delphiforum.icft.com.br/forum/viewtopic.php?t=49308
T+
E olhando com mais calma vi q postei um código errado tbm... perdão :oops:
O correto seria este :
select C.CODCARDAPIO, P1.DESCRICAO as DESCPRATO1, P2.DESCRICAO as DESCPRATO2, P3.DESCRICAO as DESCPRATO3, P4.DESCRICAO as DESCPRATO4 from CARDAPIO C left join PRATOS P1 on (C.PRATO1 = P1.CODIGO) left join PRATOS P2 on (C.PRATO2 = P2.CODIGO) left join PRATOS P3 on (C.PRATO3 = P3.CODIGO) left join PRATOS P4 on (C.PRATO4 = P4.CODIGO)
Fiz comparação dentro do ON pelo CODCARDAPIO... nada haver...
Aqui tem explicação sobre joins de ´quem entende´... :D
http://delphiforum.icft.com.br/forum/viewtopic.php?t=49308
T+
GOSTEI 0
Delphi32
14/10/2004
Pô galera, foi malz ae... eu fiquei tão empolgado com essa SQL que realmente tinha esquecido de mencionar que para o Firebird eu tive que remover os ´as´ como o Vinicius2k falou e agora há pouco antes de ver esses novos posts eu descobri que realmente algumas linhas não estavam sendo retornadas pela SQL, então eu também troquei os INNER JOIN por LEFT JOIN.
E quanto a minha pergunta sobre as FKs é que eu queria saber se com a existência delas essa consulta seria mais rápida. Isso porque hoje eu tenho 2.158 pratos cadastrados e 41.292 cardápios cadastrados... Vou fazer um teste para ver como fica a consulta com e sem as FKs...
Valeu ae!
E quanto a minha pergunta sobre as FKs é que eu queria saber se com a existência delas essa consulta seria mais rápida. Isso porque hoje eu tenho 2.158 pratos cadastrados e 41.292 cardápios cadastrados... Vou fazer um teste para ver como fica a consulta com e sem as FKs...
Valeu ae!
GOSTEI 0
Vinicius2k
14/10/2004
O que ocorre nas FKs é que, dependendo do select, a performance aumenta porque quando vc as cria, são criados indices para suas colunas automaticamente... mas estes índices podem ser criados por vc sem necessidade de FKs, é por isso que eu mencionei que ficaria a seu critério seu uso, que basicamente, só garantem a integridade referencial no banco de dados...
T+
T+
GOSTEI 0