ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Problemas com uma consulta complexa [ RESOLVIDO ]

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
dooux
Novato
Novato


Registrado: Terça-Feira, 2 de Junho de 2015
Mensagens: 22

MensagemEnviada: Seg Jan 16, 2017 4:16 pm    Assunto: Problemas com uma consulta complexa [ RESOLVIDO ] Responder com Citação

Bom dia amigos, estou com um problema e não estou conseguindo
resolve-lo, talvez por inexperiência, ou por estar com a cabeça cheia
mesmo, enfim, não consigo fazer da forma correta.

Tenho uma tabela chamada MENSALISTAS, onde tenho um campo que
diz a quantidade de vagas que um mensalista pode ter num estacionamento
(MEN_VAGAS)
Esta tabela contém o campo chave (ID_MENSALISTA), e está relacionada
com outra tabela que contém os veículos destes mensalistas.

No movimento do patio que usa uma tabela chamada TMP_LANCAMENTOS,
possui o campo(TMP_PLACA), preciso saber quando um mensalista
já excedeu seu numero de vagas no patio, levando-se em conta que uma
de suas placas já está no pátio, sabendo-se que ele pode ter mais de
um carro cadastrado, mas so pode usar aquele numero de vagas,
se por exemplo ele paga só por uma vaga e alguém já entrou no pátio
com outro carro daquele mensalista, o carro dele deve entrar
como (TIPO=A) "Avulso" e não como (TIPO=M) que era referente a
Mensalista, assim será cobrado a taxa de permanência normal do veiculo
no patio.
Não estou sabendo montar uma consulta que me dê esse resultado
envolvendo as três tabelas a seguir.
se alguém já passou por algo parecido, ou sabe com montar uma consulta
e puder me ajudar ficarei extremamente grato, já tentei de várias formas,
mas sempre resulta em algum erro. Tentei a seguinte consulta mas
também da erro:
//*******************************************************
Select
VM.ID_MENSALISTA,
VM.VEI_PLACA,
M.ID_MENSALISTA,
M.MEN_VAGAS
from VEICULOS_MENSALISTAS VM, MENSALISTAS M
where
VM.ID_MENSALISTA = M.ID_MENSALISTA
AND
VM.VEI_PLACA in (select TMP_PLACA from TMP_LANCAMENTOS)

//*******************************************************

Alguém pode dar uma sugestão ou dica.

Como saber se na tabela de LANCAMENTOS já existe uma placa do mensalista que está entrando com outra placa, se exceder o
limites de vagas do campo(MEN_VAGAS) ele mudar o campo TMP_TIPOLANCAMENTO para "A" ao invés de "M" como já ocorre,

Segue abaixo as tabelas de maneira bem resumida, apenas com campos mais necessários:

MENSALISTAS
(ID_MENSALISTA)*
MEM_NOME
MEM_SITUACAO
(MEM_VAGAS)


VEICULOS_MENSALISTAS
VEI_PLACA
ID_VEICULO
(ID_MENSALISTA)*

LANCAMENTOS
ID_LANCAMENTO
(TMP_PLACA)*
TMP_TIPOLANCAMENTO ( A=AVULSO M=MENSALISTA C=CONVENIO )
ID_USUARIO



Desde já agradeço.


Editado pela última vez por dooux em Qua Fev 01, 2017 3:38 pm, num total de 2 vezes
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
joemil
Moderador
Moderador


Registrado: Quinta-Feira, 25 de Março de 2004
Mensagens: 9100
Localização: Sinop-MT

MensagemEnviada: Ter Jan 17, 2017 8:17 am    Assunto: Responder com Citação

veja se isto funciona

Código:
SELECT m.mem_nome,
   m.mem_vagas,
   vm.vei_placa,
   COUNT(l.tmp_placa) AS qtde
FROM mensalidas m
INNER JOIN veiculos_mensalistas vm ON vm.id_mensalista = m.id_mensalista
INNER JOIN lancamentos l ON l.tmp_placa = vm.vei_placa
GROUP BY m.mem_nome,
   m.mem_vagas,
   vm.vei_placa

_________________
<b>SEMPRE COLOQUE [RESOLVIDO] NO SEU POST</b>
Enviar imagens: http://tinypic.com/
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
dooux
Novato
Novato


Registrado: Terça-Feira, 2 de Junho de 2015
Mensagens: 22

MensagemEnviada: Ter Jan 17, 2017 2:22 pm    Assunto: Responder com Citação

joemil escreveu:
veja se isto funciona

Código:
SELECT m.mem_nome,
   m.mem_vagas,
   vm.vei_placa,
   COUNT(l.tmp_placa) AS qtde
FROM mensalidas m
INNER JOIN veiculos_mensalistas vm ON vm.id_mensalista = m.id_mensalista
INNER JOIN lancamentos l ON l.tmp_placa = vm.vei_placa
GROUP BY m.mem_nome,
   m.mem_vagas,
   vm.vei_placa


//*********************************************************

Oi amigo, boa tarde e obrigado.
Tentei dessa forma que vc me sugeriu, ele funciona por exemplo nos primeiros dois carros de um mensalista, mas quando passo para outro mensalista com mais de um carro, no primeiro carro a pesquisa já retorna como se tivesse um na consulta.

copiei parte do código aqui:

Código:
// **********************************************************************************************
// CONSULTA CRIADA
var
  sSql         : string;
  ibqVeiculosMensalistaPatio : TIBQuery;
begin
  sSql :=
    'SELECT                ' +
    '  VM.ID_MENSALISTA,   ' +
    '  VM.VEI_PLACA,       ' +
    '  M.ID_MENSALISTA,    ' +
    '  M.MEN_NOME,         ' +
    '  M.MEN_VAGAS,        ' +
    '  T.TMP_TIPOLANCAMENTO,  ' +
    '  T.TMP_SITUACAO,        ' +
    '  COUNT(T.TMP_PLACA) AS QTDE  ' +
    'FROM                 ' +
    '  MENSALISTAS M      ' +
    'INNER JOIN VEICULOS_MENSALISTAS VM ON VM.ID_MENSALISTA = M.ID_MENSALISTA ' +
    'INNER JOIN TMP_LANCAMENTOS T ON ' + QuotedStr(txtPlaca.Text) + ' = VM.VEI_PLACA ' +
    'WHERE  ' +
    '  T.TMP_TIPOLANCAMENTO = ' + QuotedStr('M') + '  ' +
    'AND    ' +
    '  T.TMP_SITUACAO =       ' + QuotedStr('A') + '  ' +
    'GROUP BY    VM.ID_MENSALISTA, VM.VEI_PLACA, M.ID_MENSALISTA, M.MEN_NOME, M.MEN_VAGAS, T.TMP_TIPOLANCAMENTO, T.TMP_SITUACAO ' ;

  ibqVeiculosMensalistaPatio := CriaIb(ibqVeiculosMensalistaPatio);
  ExecutaSql(ibqVeiculosMensalistaPatio,sSql);

  if ibqVeiculosMensalistaPatio.RecordCount > 0 then
  begin
      lMensalista               := True;
      nVagasMensalista          := ibqVeiculosMensalistaPatio.FieldByName('MEN_VAGAS').AsInteger;
      nVeiculosMensalistaNoPatio := ibqVeiculosMensalistaPatio.FieldByName('QTDE').AsInteger; ;
  end
  else
  begin
      nVeiculosMensalistaNoPatio := 0;
      nVagasMensalista           := ibqVeiculosMensalistaPatio.FieldByName('MEN_VAGAS').AsInteger;
  end;

  ibqVeiculosMensalistaPatio.Destroy;

end;

// **********************************************************************************************

// VERIFICA SE JÁ EXISTE UMA PLACA DE MENSALISTA NO PÁTIO E DA ENTRADA COMO A=AVULSO

        IF not BuscaLancamentoAberto(txtPlaca.Text) Then
        begin
//                  nVagasMensalista          := ibqMensalista.FieldByName('MEN_VAGAS').AsInteger;
             BuscaVeiculoMensalistaPatio(txtPlaca.Text);
             if  (  nVeiculosMensalistaNoPatio >= nVagasMensalista ) then
             begin
                Application.MessageBox('O MENSALISTA EXCEDEU O NUMERO DE VAGAS CONTRATADAS, ESSE VEÍCULO SERÁ LANCADO COMO AVULSO!','ATENÇÃO', MB_OK + MB_ICONWARNING);
                lBloquearVagas := true;
             end
             else
               BuscaVeiculoMensalista(txtPlaca.Text);
          end;
//****************************


Talvez eu esteja dando mole em algo, já rodei com break points pra testar
e sempre após funcionar no primeiro e entrar um carro como M=Mensalista
e outro como A=Avulso, o próximo que tento já retorna como se tivesse
um carro no pátio. :/
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
dooux
Novato
Novato


Registrado: Terça-Feira, 2 de Junho de 2015
Mensagens: 22

MensagemEnviada: Qua Fev 01, 2017 3:37 pm    Assunto: RESOLVIDO Responder com Citação

Olá galera, consegui resolver fazendo uma procedure executando duas consultas diferentes e depois testando o resultado armazenado em cada uma.
Obrigado pela força.

procedure BuscaVeiculoMensalistaPatio(sPlaca: string);
var
sSql1, sSqlIdMensalista : string;
ibqVeiculosMensalistaPatio : TIBQuery;
CONT : Integer;
nVeiculosTabLancamentoMensalista : Integer;
nVeiculosEntrandoPatio : Integer;
begin

nControleVagas := 0 ;
nVeiculosMensalistaNoPatio := 0 ;
nVeiculosTabLancamentoMensalista := 0 ;
nVeiculosEntrandoPatio := 0 ;
sSql1 := '';
sSqlIdMensalista := '';

//*****************************************************************************
sSqlIdMensalista :=
'SELECT ' +
' M.ID_MENSALISTA, ' +
' M.MEN_NOME, ' +
' M.MEN_VAGAS, ' +
' VM.ID_MENSALISTA, ' +
' VM.VEI_PLACA ' +
'FROM ' +
' MENSALISTAS M ' +
' INNER JOIN VEICULOS_MENSALISTAS VM ON (M.ID_MENSALISTA = VM.ID_MENSALISTA) ' +
'WHERE VM.VEI_PLACA = ' + QuotedStr(txtPlaca.Text) ;

// showmessage(sSqlIdMensalista);

ibqVeiculosMensalistaPatio := CriaIb(ibqVeiculosMensalistaPatio);
ExecutaSql(ibqVeiculosMensalistaPatio,sSqlIdMensalista);

idMensalistaControle := ibqVeiculosMensalistaPatio.FieldByName('ID_MENSALISTA').AsInteger;
nControleVagas := ibqVeiculosMensalistaPatio.FieldByName('MEN_VAGAS').AsInteger ;
nVeiculosEntrandoPatio := ibqVeiculosMensalistaPatio.RecordCount;

//*****************************************************************************
sSql1 :=
'SELECT ' +
' M.ID_MENSALISTA, ' +
' M.MEN_NOME, ' +
' M.MEN_VAGAS, ' +
' LC.ID_MENSALISTA, ' +
' LC.PLACA, ' +
' LC.DATAENTRADA, ' +
' LC.DATASAIDA, ' +
' LC.HORAENTRADA, ' +
' LC.HORASAIDA ' +
'FROM ' +
' MENSALISTAS M ' +
' INNER JOIN LANCAMENTOS_MENSALISTAS LC ON M.ID_MENSALISTA = LC.ID_MENSALISTA ' +
'WHERE LC.DATASAIDA IS NULL ' +
'AND ' +
' LC.ID_MENSALISTA = ' + IntToStr(idMensalistaControle) ;


ibqVeiculosMensalistaPatio := CriaIb(ibqVeiculosMensalistaPatio);
ExecutaSql(ibqVeiculosMensalistaPatio,sSql1);

//******************************************************************************
// APÓS COLOCAR ESSE PEQUENO CÓDIGO AQUI, O RecordCount PASSOU A EXIBIR A QTDE CORRETA DE REGISTROS / PORQUE ?
cont:=0;
while not ibqVeiculosMensalistaPatio.eof do
begin
inc(cont);
ibqVeiculosMensalistaPatio.Next;
// showmessage('REGISTRO ' + iNTtOSTR(cont) );
end;
// showmessage(sSql1);
// showmessage('NUMERO DE REGISTROS ENCONTRADOS NA TABELA LANCAMENTOS_MENSALISTAS : ' + iNTtOStr( ibqVeiculosMensalistaPatio.RecordCount ) );
nVeiculosTabLancamentoMensalista := ibqVeiculosMensalistaPatio.RecordCount;
//******************************************************************************

IF nControleVagas = 0 THEN

nControleVagas := ibqVeiculosMensalistaPatio.FieldByName('MEN_VAGAS').AsInteger ;

nVeiculosMensalistaNoPatio := nVeiculosEntrandoPatio + nVeiculosTabLancamentoMensalista; //ibqVeiculosMensalistaPatio.RecordCount ; // nVeiculosMensalistaNoPatio + ibqVeiculosMensalistaPatio.RecordCount + 1 ; ibqVeiculosMensalistaPatio.RecordCount;


ibqVeiculosMensalistaPatio.Destroy;

end;
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB