[firebase-br] SQL/Consulta complexa - Firebird 2.1
Eduardo Belo
beloelogica em gmail.com
Qua Mar 10 16:29:20 -03 2010
Puxa vida Sandro, funcionou perfeitamente.
Muito, muito obrigado pela ajuda. Fico te devendo essa.
Grande abraço!
Em 10 de março de 2010 07:10, Sandro Souza <escovadordebits em gmail.com> escreveu:
> Bom dia/tarde Eduardo.
>
> Grande Eduardo, infelizmente você não conseguirá o resultado que você deseja
> apenas com um simples SELECT.
>
> Por favor, teste a seguinte stored procedure:
>
> SET TERM ^ ;
>
> CREATE OR ALTER PROCEDURE LISTA_INSTRUTORES RETURNS (
> ID_INSTRUTOR INTEGER,
> INSTRUTOR VARCHAR(80),
> EMAIL VARCHAR(80),
> TELEFONE VARCHAR(14)
> )AS
> DECLARE VARIABLE COUNT_EMAILS INTEGER;
> DECLARE VARIABLE COUNT_TELEFONES INTEGER;
> DECLARE VARIABLE COUNT_MAIOR INTEGER;
> DECLARE VARIABLE INDICE INTEGER;
> BEGIN
> -- Laço de leitura dos instrutores.
> FOR SELECT ID_INSTRUTOR, INSTRUTOR FROM INSTRUTORES ORDER BY 2 INTO
> :ID_INSTRUTOR, :INSTRUTOR DO
> BEGIN
> -- Obtém a quantidade de emails do instrutor atual.
> SELECT COUNT(*) FROM EMAILS WHERE ID_INSTRUTOR = :ID_INSTRUTOR INTO
> COUNT_EMAILS;
> -- Obtém a quantidade de telefones do instrutor atual.
> SELECT COUNT(*) FROM TELEFONES WHERE ID_INSTRUTOR = :ID_INSTRUTOR INTO
> COUNT_TELEFONES;
> -- Inicializa os parâmetros de email e telefone a serem retornados.
> EMAIL = NULL;
> TELEFONE = NULL;
> -- O instrutor atual não tem email e nem mesmo um telefone?
> IF ((COUNT_EMAILS = 0)AND(COUNT_TELEFONES = 0)) THEN
> -- Retorna um registro/linha contendo apenas o código e o nome do
> instrutor atual.
> SUSPEND;
> ELSE
> BEGIN
> -- Tem mais emails que telefones?
> IF (COUNT_EMAILS > COUNT_TELEFONES) THEN
> -- A maior quantidade é a de emails.
> COUNT_MAIOR = COUNT_EMAILS;
> ELSE
> -- A maior quantidade é a de telefones.
> COUNT_MAIOR = COUNT_TELEFONES;
> -- Inicializa o índice dos registros de email e telefone.
> INDICE = 1;
> -- Laço de leitura dos emails e telefones.
> WHILE (INDICE <= COUNT_MAIOR) DO
> BEGIN
> -- Todos os emails do instrutor atual foram lidos?
> IF (INDICE > COUNT_EMAILS) THEN
> -- Sem mais emails.
> EMAIL = NULL;
> ELSE
> -- Obtém o email da vez.
> SELECT FIRST 1 SKIP (:INDICE - 1) EMAIL FROM EMAILS WHERE
> ID_INSTRUTOR = :ID_INSTRUTOR INTO :EMAIL;
> -- Todos os telefones do instrutor atual foram lidos?
> IF (INDICE > COUNT_TELEFONES) THEN
> -- Sem mais telefones.
> TELEFONE = NULL;
> ELSE
> -- Obtém o telefone da vez.
> SELECT FIRST 1 SKIP (:INDICE - 1) TELEFONE FROM TELEFONES WHERE
> ID_INSTRUTOR = :ID_INSTRUTOR INTO :TELEFONE;
> -- Retorna mais um registro/linha.
> SUSPEND;
> -- Atualiza o índice.
> INDICE = INDICE + 1;
> END -- WHILE
> END -- ELSE
> END -- FOR
> END^
>
> SET TERM ; ^
>
> Agora é só testar: SELECT * FROM LISTA_INSTRUTORES
>
> Espero ter ajudado mais que atrapalhado. :D
>
> Em 9 de março de 2010 12:17, Eduardo Belo <beloelogica em gmail.com> escreveu:
>>
>> Amigos,
>>
>> Tenho as seguintes tabelas:
>>
>> TABLE INSTRUTORES
>> ID_INSTRUTOR INTEGER NOT NULL,
>> INSTRUTOR VARCHAR(80)
>>
>> TABLE EMAILS
>> ID_EMAIL INTEGER NOT NULL,
>> ID_INSTRUTOR INTEGER NOT NULL,
>> EMAIL VARCHAR(80)
>>
>> TABLE TELEFONES
>> ID_TELEFONE INTEGER NOT NULL,
>> ID_INSTRUTOR INTEGER NOT NULL,
>> TELEFONE VARCHAR(14)
>>
>> CHAVE RELACIONAMENTO = ID_INSTRUTOR
>>
>> ****************************************************
>>
>> Efetuando o select abaixo:
>>
>> SELECT
>> INSTRUTORES.ID_INSTRUTOR,
>> INSTRUTORES.INSTRUTOR,
>> EMAILS.EMAIL,
>> TELEFONES.TELEFONE
>> FROM TELEFONES
>> INNER JOIN INSTRUTORES ON (TELEFONES.ID_INSTRUTOR =
>> INSTRUTORES.ID_INSTRUTOR)
>> INNER JOIN EMAILS ON (INSTRUTORES.ID_INSTRUTOR = EMAILS.ID_INSTRUTOR)
>>
>> Retorno consulta:
>>
>> INSTRUTOR EMAIL TELEFONE
>> --------------------------------------------------
>> MARIA maria em hotmail.com 8605-9395
>> JOSE jose em yahoo.com.br 3445-6181
>> JOSE jose@@hotmail.com 9998-8294
>> JOAO joao em gmail.com 9133-3824
>> JOAO joao em gmail.com 3181-8037
>> JOAO joao em gmail.com 3426-9322
>> JOAO joao em yahoo.com.br 9133-3824
>> JOAO joao em yahoo.com.br 3181-8037
>> JOAO joao em yahoo.com.br 3426-9322
>>
>>
>> Observem que no caso de JOAO ele tem 2 email e 3 telefones e
>> retorna duplicado nos telefones. Eu preciso que nesse caso ele
>> retorne 2 emails e 3 telefones:
>>
>> JOAO joao em gmail.com 9133-3824
>> JOAO joao em yahoo.com.br 3181-8037
>> JOAO 3426-9322
>>
>> Tem como fazer um SELECT para retornar assim ?
>>
>> Ou existe algum erro na minha modelagem ?
>>
>> Eu preciso de tabelas idependentes de e-mail e teofne uma vez
>> que o instrutor pode ter vários telefones e emails.
>>
>> Qual a solução para este caso?
>>
>> Agradeço a todos que ajudarem.
>>
>> ______________________________________________
>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
>> Para saber como gerenciar/excluir seu cadastro na lista, use:
>> http://www.firebase.com.br/fb/artigo.php?id=1107
>> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
>
Mais detalhes sobre a lista de discussão lista