Consulta SQL, furo de parcela.
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.
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
Curtidas 0
Respostas
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
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
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:
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.
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
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
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:
eu uso interbase/firebird...suporta sub-select ?
o que seriam esses P1 e P2 ? :oops:
GOSTEI 0
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 ?
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
17/01/2006
Ok, muito obrigado pela explicação.
Testando . . . .
Testando . . . .
GOSTEI 0
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
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
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 ?
tenho 200 000 registros na tabela...
alguma sugestao ?
GOSTEI 0
Motta
17/01/2006
Qual a chave primaria de arq_Hist ??
GOSTEI 0
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:
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
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.
A demora deva ser talvez a falta de indices, dificil saber.
GOSTEI 0
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 !
Estou certo ?
Obrigado pela ajuda !
GOSTEI 0
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.
Assim a tabela deve ter vinculo do cliente.
GOSTEI 0
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:
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 !
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
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
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.
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
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.
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