Consulta SQL, furo de parcela.

Delphi

17/01/2006

Olá a todos !

Bom, quero fazer uma consulta em sql, que me mostre furos de pagamento. Ex. tenho o cliente que paga rigorosamente em dia, porem a 11 meses atras ele esqueceu de pagar aquela parcela. Como faco um relatorio que me mostre quais sao os clientes que tem esse tipo de furo nas parcelas ?


Obrigado.


Geisonc

Geisonc

Curtidas 0

Respostas

Motta

Motta

17/01/2006

Relate a estrutura da tabela, como é feita a marcação de pagamento.

mas supondo seria algo assim :


SELECT C.NOME,P.DT_VENC,P.VALOR
FROM CLIENTES C,PARCELAS P
WHERE C.COD = P.CODCLI
AND P.DT_PGTO IS NULL


GOSTEI 0
Geisonc

Geisonc

17/01/2006

Deixa eu explicar melhor, resumindo.

Quero tirar um relatorio dos clientes que estao a 10 dias em atraso.
Até ai tudo bem, eu consegui, porem...

Porem se o cliente está devendo os 10 dias que eu estipulei e mais algum mes que nao foi pago ele, nao deve constar no relatorio.

A instrucao SQL está assim:

        DataModule1.QProcCobranca.SQL.Clear;
        DataModule1.QProcCobranca.SQL.Add(´select * from arq_Hist where (grupo = :grupo) and(paga is null) and (venc between :data1 and :data2) order by venc´);
        Datamodule1.QProcCobranca.ParamByName(´grupo´).AsString:=ecidade.Items[ecidade.itemindex];
        Datamodule1.QProcCobranca.ParamByName(´data1´).Asdate:=data1;
        Datamodule1.QProcCobranca.ParamByName(´data2´).Asdate:=data2;
        DataModule1.QProcCobranca.Open;



Nesta instrucao ele me mostra os clientes que estao devendo em um certo periodo...

mas eu quero que ele me motre somente dakele periodo, caso ele tenha outra parcela nao paga em outro mes, ele nao entre no relatorio.


GOSTEI 0
Motta

Motta

17/01/2006

Se o bd suporta sub-select ...



select *
from parcelas p1
where .....
and not exists (select null
                      from parcelas p2
                      where p2.chave = p1.chave
                      and     p2.data_parcela <> p1.data_parcela
                      and     p2.data_pgto is null)
 



GOSTEI 0
Geisonc

Geisonc

17/01/2006

Desculpe a ignorancia, mas só pra mim entender o codigo...

eu uso interbase/firebird...suporta sub-select ?

o que seriam esses P1 e P2 ? :oops:


GOSTEI 0
Host

Host

17/01/2006

´select *
from parcelas p1
where .....
and not exists (select null
from parcelas p2
where p2.chave = p1.chave
and p2.data_parcela <> p1.data_parcela
and p2.data_pgto is null) ´

Esta sql do nosso amigo MOTTA parece resolver teu problema. E o firebird suporta tranquilamente esta sql , ja a respeito do P1 e P2 , seriam como alias da tabela....

Ao inves de ter q digitar : parcelas.data_parcela
vc digitaria o alias da tabela no sql: p1.data_parcela
so que esta pesquisa ficaria meio lenta pq ele pesquisaria duas vezes na mesma tabela, mas vai ai testa , brinca um pouco com a sql, e mede a velocidade , ñ sei se o firebird deixa criar um ´view´ , seria interessante pois seriam bufers diferentes de pesquisa... poderiamos criar um post com esta discussão!!!Dois buffers um pra tabela e outro pro view... sei la... to falando mas nem sei se da de fazer view no interbase!!!
Vou ver isto!
Mas testa a solução do Motta , q dependendo da tua estrutura dará certo!


Desculpe a ignorancia, mas só pra mim entender o codigo...
eu uso interbase/firebird...suporta sub-select ?
o que seriam esses P1 e P2 ?


GOSTEI 0
Geisonc

Geisonc

17/01/2006

Ok, muito obrigado pela explicação.

Testando . . . .


GOSTEI 0
Motta

Motta

17/01/2006

Devido ao problema (não poder existir outra parcela em aberto) requer uma leitura na mesma base o alias é para poder fazer referencia as duas instancias da tabela.

A melhor solução que vejo é um sub-select

select * 
from arq_Hist a1
where (grupo = :grupo) 
and (paga is null) 
and (venc between :data1 and :data2) 
and not exists (select * 
                      from arq_Hist a2
                     where (a2.grupo = a1.grupo) 
                     and (a2.paga is null) 
                     and (a2.venc <> a1.venc))




GOSTEI 0
Geisonc

Geisonc

17/01/2006

Montei esta consulta no isql do interbase... ele mostra a ampulheta do SQL por uns 5 segundos... depois troca para a ampulheta de ocupado... dai trava...
tenho 200 000 registros na tabela...

alguma sugestao ?


GOSTEI 0
Motta

Motta

17/01/2006

Qual a chave primaria de arq_Hist ??


GOSTEI 0
Geisonc

Geisonc

17/01/2006

Eu nao uso chave primaria, pq essa tabela junto com mais 6, sao importadas de um soft de terceiros pelo IbPum, de DBF para interbase, e eu uso apenas para consulta de dados e geração de relatórios. há gravação de dados, mas que não altera ou inclui nada na tabela arq_hist (Arquivo de Historico de Pagamentos).

A tabela arq_hist do GDB está assim:


"GRUPO"      VARCHAR(5),
  "REFER"         VARCHAR(5),
  "TIPODEB"     VARCHAR(3),
  "VALOR"      NUMERIC(5, 2),
  "VENC"       DATE,
  "PAGA"      DATE,
  "LANC"      VARCHAR(1),
  "VALOR_PAGO"NUMERIC(12, 0),
  "USUARIO"VARCHAR(10),
  "VENCSEQ"DATE,
  "SEQ_LOC"NUMERIC(9, 0),
  "VALOR_GAR"NUMERIC(6, 0),
  "ORDEM"                NUMERIC(4, 0),
  "CODCOBR"VARCHAR(3),
  "CANC_ALTZ"VARCHAR(1),
  "DATA"                DATE,
  "EXPORTA"DATE,
  "DATAAUX"DATE,
  "VALOR_AUX"NUMERIC(12, 0),
  "SEQUENCIA"INTEGER,
  "INSCRICAO"FLOAT,
  "USUARIOSAF"VARCHAR(30),
  "EMUSO"                VARCHAR(1)



GOSTEI 0
Motta

Motta

17/01/2006

E que na query de sub-select tem de ter um WHERE que garanta que serão verificados só os registros da mesma parte da chave , clientes no seu caso grupo

A demora deva ser talvez a falta de indices, dificil saber.


GOSTEI 0
Geisonc

Geisonc

17/01/2006

entao no caso , ele ta comparando o primeiro select com o segundo select ? mas creio eu que se for assim, não dará certo pois o campo grupo é um cadastro de cidades, e tem varios registros com a mesma cidade, mas caso for este o problema, pode-se trocar pelo campo inscricao, pois ha a penas um numero de inscricao pra cada cliente.

Estou certo ?

Obrigado pela ajuda !


GOSTEI 0
Motta

Motta

17/01/2006

Isto, o que o sub-select faz e ver a regra (não ter nenhuma outra parcela em aberto).

Assim a tabela deve ter vinculo do cliente.


GOSTEI 0
Geisonc

Geisonc

17/01/2006

Eu entendi o codigo, mas ainda me restam duvidas.. pois ainda mostra dados que eu nao quero, ou seja, ta mostrando clientes que tem mais de uma parcela em atraso, e eu só quero que me mostre o tanto de dias que eu estipulei de atrazo....

este codigo:
select * from arq_hist a1 where 
(venc between :data1 and :data2) and (paga is null) and 
(grupo = :grupo) and not exists  (select * from arq_hist a2 where (a2.paga is null) and (a2.inscricao = a1.inscricao) and 
(a2.venc <> a1.venc))


Como nao tem inscrição no primeiro select, ele verifica mesmo assim a inscricao ? pois se eu colocar para consultar a inscricao no primeiro select ele vai me trazer apenas a que eu colocar e nao todos o clientes... e colocando no segundo select, tenho duvidas se ele procura ...
bom, mesmo assim, neste caso ele ainda mostra clientes com varias parcelas em atraso...

Agradeço o empenho para me ajudar !


GOSTEI 0
Motta

Motta

17/01/2006

select * from arq_hist a1 where 
(venc between :data1 and :data2) and (paga is null) and 
(grupo = :grupo) and 
(:DTHOJE - A1.VENC) >= :NUMDIAS
not exists  (select * from arq_hist a2 
where         (a2.paga is null) and 
(a2.inscricao = a1.inscricao) and 
(a2.venc <> a1.venc)) 



:DTHOJE - DATA DO DIA (EXISTE UMA FUNCTION PARA ISTO PROVALVEMENTE)
:NUMDIAS - NUM DE DIAS QUE VC QUER FILTRAR


GOSTEI 0
Host

Host

17/01/2006

Esta assim:
select * from arq_hist a1 where
(venc between :data1 and :data2) and (paga is null) and
(grupo = :grupo) and not exists (select * from arq_hist a2 where (a2.paga is null) and (a2.inscricao = a1.inscricao) and
(a2.venc <> a1.venc))

bom.... tem pouca mudança mas faria o seguinte teste. Da forma que esta não deveria dar problema.... mas eu ja tive... eu faria da seguinte forma :

select * from arq_hist a1
where (a1.venc between ´field data´ and ´field data´)
and (a1.paga is null)
and (a1.grupo = ´field grupo´)
and not exists (select * from arq_hist a2
where (a2.paga is null)
and (a2.inscricao = a1.inscricao)
and (a2.venc <> a1.venc))
as vezes me da problemas qdo defino parametros pra sql.... jogo o campo direto na sql... me ocorre este problema normalmente entre datas.


GOSTEI 0
Host

Host

17/01/2006

Esta assim:
select * from arq_hist a1 where
(venc between :data1 and :data2) and (paga is null) and
(grupo = :grupo) and not exists (select * from arq_hist a2 where (a2.paga is null) and (a2.inscricao = a1.inscricao) and
(a2.venc <> a1.venc))

bom.... tem pouca mudança mas faria o seguinte teste. Da forma que esta não deveria dar problema.... mas eu ja tive... eu faria da seguinte forma :

select * from arq_hist a1
where (a1.venc between ´field data´ and ´field data´)
and (a1.paga is null)
and (a1.grupo = ´field grupo´)
and not exists (select * from arq_hist a2
where (a2.paga is null)
and (a2.inscricao = a1.inscricao)
and (a2.venc <> a1.venc))
as vezes me da problemas qdo defino parametros pra sql.... jogo o campo direto na sql... me ocorre este problema normalmente entre datas.


GOSTEI 0
POSTAR