Filtros no SQL

Delphi

09/04/2006

D7+IBO+Firebird 1.5

Tenho um tabela TBCARASS com 4 campos
(AUTINC,CODASS,NUMEMI,QTDPAG), onde

CODASS=Código do Associado
NUMEMI= Número de emissão do carnê
QTDPAG= Quantidade de parcelas pagas

Supondo que estes são os dados gravados
nela:
1 0010 01 1
2 0015 05 2
3 0010 02 5
4 0010 03 3
5 0015 06 7

Como extrair num SELECT ou até mesmo
numa STORED PROCEDURE o último número
de Emissões (NUMEMI) de cada Sócio (CODASS),
porém cuja QTDPAG seja maior, por exemplo a 3.

Neste exemplo acima, deveria apresentar somente como
resultado o CODASS = 0015 pois a QTDPAG da última emissão do
CODASS = 0010 não é maior que 3...

Espero uma sugestão...

Susana


Susi

Susi

Curtidas 0

Respostas

Edilcimar

Edilcimar

09/04/2006

Se entendi direito seria
Select * from tabela where QTDPAG >= 3


GOSTEI 0
Susi

Susi

09/04/2006

Olá Edilcimar,

Veja, eu preciso que além da QTDPAG>=3, que seja selecionada somente o último NUMEMI daquele CODASS.

Explicando melhor: eu tenho uma tabela de Associados e outra Tabela de Carnes Associados, onde tenho o NUMEMI(número de emissão do carne).
Um mesmo Associado pode ter diversos NUMEMI diferentes. Eu preciso pegar o último(maior) NUMEMI de cada associado e daí sim, verificar se QTDPAG>=3.

Tens uma idéia de como fazer isso?

Fico no aguardo

Susana

Se entendi direito seria Select * from tabela where QTDPAG >= 3



GOSTEI 0
Motta

Motta

09/04/2006

tabela TBCARASS com 4 campos 
(AUTINC,CODASS,NUMEMI,QTDPAG), onde 

select CODASS,max(NUMEMI) NUMEMI
from TBCARASS 
where QTDPAG>=3
group by CODASS


Creio que é isto ...


GOSTEI 0
Susi

Susi

09/04/2006

Olá Mota,

Você colocou:

select CODASS,max(NUMEMI) NUMEMI
from TBCARASS
where QTDPAG>=3
group by CODASS
[/code]

Creio que é isto ...


Não é isso ainda que preciso. No seu código, acontece o seguinte, ele primeiro filtra os associados que tem QTDPAG>=3, e só depois pega o max(NUMEMI), o que não resolve, visto que as vezes acontece de o máximo carne emitido ainda não ter 3 parcelas pagas....

Eu preciso PRIMEIRO pegar o max(NUMEMI) de cada associado e DESTES filtrar somente os que tenham QTDPAG>=3.

Não sei se consegui me fazer entender, mas é isso...

Continuo testando e aguardando sugestões...

Susana


GOSTEI 0
Edilcimar

Edilcimar

09/04/2006

where qtdpag = max(numemi) não funciona?


GOSTEI 0
Susi

Susi

09/04/2006

Olá Edilcimar,

Eu acho que vc não entendeu muito bem o meu problema... Tentei explicar melhor num post anterior para o Motta, se quiser dar uma olhada...

Como vou colocar : where qtdpag = max(numemi) se qtdpag é uma coisa e numemi outra?

QQuer solução estou por aqui...

Susana


GOSTEI 0
Motta

Motta

09/04/2006

susi , acho que funciona minha qry pois que não tiver 3 pagas não aparece na lista.


GOSTEI 0
Susi

Susi

09/04/2006

Olá Motta,

Desde já agradeço sua atenção à minha dúvida, mas veja os dados a seguir:

1 0010 01 1
2 0015 05 2
3 0010 02 5
4 0010 03 3
5 0015 06 7
6 0010 04 1

Acrescentei mais um dado...

Bom, no associado 0010 o maior NUMEMI é o 04, só que eu a QTDPAG é menor que 3, então esse associado não deve aparecer na minha lista...

Só que utilizando sua query, ele primeiro busca QTDPAG>=3, ou seja, aparece listado o associado 0010, com o >NUMEMI 03, quando na verdade
não seria esse meu propósito...

Talvez vc achou que deu certo, porque eu não tinha colocado um dado onde no maior NUMEMI, a QTDPAG não atendesse o filtro...

Espero que tenha entendido...

Eu já estou 3 dias , tentando resolver , e tá difícil...

Um abraço

Susana


GOSTEI 0
Motta

Motta

09/04/2006

minha query pegaria 4 0010 03 3
para o cliente 10, nao ?


GOSTEI 0
Susi

Susi

09/04/2006

Motta,

Veja bem, eu preciso que analise o ultimo(maior) NUMEMI que no CODASS 0010 é o 04.

minha query pegaria 4 0010 03 3 para o cliente 10, nao ?


Nesse registro que vc pegou, o NUMEMI é o 03 ou seja não é o último NUMEMI desse associado...

Deu pra entender?

Susana


GOSTEI 0
Martins

Martins

09/04/2006

[b:cf5b696ccf]AUTINC,CODASS,NUMEMI,QTDPAG[/b:cf5b696ccf] 1..........0010........01............ 1 2..........0015........05............ 2 3..........0010........02............ 5 4..........0010........03............ 3 [b:cf5b696ccf][color=red:cf5b696ccf]5..........0015........06............ 7 [/color:cf5b696ccf][/b:cf5b696ccf] 6..........0010........04............ 1


daqui vc quer q seja retornado apenas o registro

[color=red:cf5b696ccf]5..........0015........06............ 7 [/color:cf5b696ccf]


pq é numemi é o maior (7), e a quantidade paga é maior q 3, já
6..........0010........04............ 1


o maior numemi é 4 mas a qtdpag é menor do q 3.

nesse caso acho q vc terá q usar SP para obter o resultado. pq com um simples select não sei se resolveria.

com o SQL do nosso colega Motta, o resultado seria.
[color=green:cf5b696ccf]4..........0010........03............ 3 [/color:cf5b696ccf] [b:cf5b696ccf][color=red:cf5b696ccf]5..........0015........06............ 7 [/color:cf5b696ccf][/b:cf5b696ccf]


usando assim como teste apenas...
select codass, max(numemi) as emissao from testes2 where qtdpag >= 3 and testes2.numemi > X group by codass


o resultado seria
[color=red:cf5b696ccf]5..........0015........06............ 7 [/color:cf5b696ccf]


Espero ter entendido o q vc deseja.


GOSTEI 0
Susi

Susi

09/04/2006

Olá, Martins,

Seja bem vindo ao meu ´problema´...

Como você pode verificar, o Sql do Motta, não atende o que preciso...

Já no seu Sql, o resultado está correto, mas não entendi o que seria o ´X´ em:

[color=blue:27ee07e1da]select codass, max(numemi) as emissao from testes2 where qtdpag >= 3 and testes2.numemi > X group by codass[/color:27ee07e1da]

Concordo com vc que o caminho deve ser criar SP, mas ainda não consegui...

Tem alguma idéia? Ou algum exemplo em que eu possa me basear?

Desde já agradeço

Susana


GOSTEI 0
Motta

Motta

09/04/2006

Vamos ver se me caiu a ficha ...

1) Monte uma view com o máximo de cada cliente

CREATE VIEW MAXIMOS AS 
select AUTINC,CODASS,NUMEMI,QTDPAG
from TBCARASS T1
where T1.NUMEMI = 
    (SELECT MAX(T2.NUMEMI)
     FROM  TBCARASS T2
     WHERE T2.CODCLI = T1.CODCLI)  


2) use a view fazendo o teste nela

SELECT * FROM MAXIMUS
WHERE QTDPAG > 3


???????


GOSTEI 0
Martins

Martins

09/04/2006

Não testei a solução do colega [b:b6b076dae4]Motta[/b:b6b076dae4] pq não tenho firebird aqui, quanto ao [b:b6b076dae4]X[/b:b6b076dae4] seria ele um parametro, uma informação externa q eu usei apenas para exemplificar um teste.

Quanto ao uma SP q possa fazer o q vc deseja, imagino q essa deva servir como base para vc montar a sua.

CREATE PROCEDURE SPMAX (
    PAGAS INTEGER,
    EMISSAO INTEGER)
RETURNS (
    CODASS INTEGER,
    NUMEMI INTEGER)
AS
begin
  /* Procedure Text */
 for Select codass, max(numemi)
  From testes2 where qtdpag >= :pagas and numemi >= :emissao group by codass
  into :codass, :numemi
 do
  suspend;
end


pode chamar a [b:b6b076dae4]SP[/b:b6b076dae4] assim.

select * from spmax(3, (select max(numemi) from testes2));


Boa sorte [b:b6b076dae4]susi[/b:b6b076dae4]


GOSTEI 0
Susi

Susi

09/04/2006

Amigos Motta e Martins,

Ufa!!! A View do colega Motta, funcionou perfeitamente... Aprendi um bocado, visto que nunca tinha usado esse recursos de views...

Quanto a SP, ela não retorna nada... Será que tem algum parametro errado na nossa montagem???

Martins, se tiveres uma idéia do que poderia estar errado, poderias me dar um toque, visto que também tenho interesse de aprender a usar SP.

No mais, obrigado a todos

Um abraço :D :D

Susana


GOSTEI 0
Martins

Martins

09/04/2006

Amigos Motta e Martins, Ufa!!! A View do colega Motta, funcionou perfeitamente... Aprendi um bocado, visto que nunca tinha usado esse recursos de views... Quanto a SP, ela não retorna nada... Será que tem algum parametro errado na nossa montagem??? Martins, se tiveres uma idéia do que poderia estar errado, poderias me dar um toque, visto que também tenho interesse de aprender a usar SP. No mais, obrigado a todos Um abraço :D :D Susana


Como vc usou a SP? Quais componentes vc usou? Teste-a pelo IbExpert se tiver.

O código da Sp está normal, pedi para um colega rodar a Sp para mim e está normal.

Esse código cria a Stored Procedure, teste no IbConsole, IbExpert, EMS, etc...

CREATE PROCEDURE SPMAX ( 
    PAGAS INTEGER, 
    EMISSAO INTEGER) 
RETURNS ( 
    CODASS INTEGER, 
    NUMEMI INTEGER) 
AS 
begin 
  /* Procedure Text */ 
 for Select codass, max(numemi) 
  From testes2 where qtdpag >= :pagas and numemi >= :emissao group by codass 
  into :codass, :numemi 
 do 
  suspend; 
end


Rodando-a por uma das ferramentas acima, o código seria o já citado anteriormente.

select * from spmax(3, (select max(numemi) from testes2))


Só q não sei qual componente vc usou para executar a SP e lembre-se q vc tem q informar os paramentros.

[color=red:4df9776f31][b:4df9776f31]select * from spmax(Param1, Param2)[/b:4df9776f31][/color:4df9776f31]


GOSTEI 0
Susi

Susi

09/04/2006

Oi, Martins,

Estou usando IBExpert...

Passei os parâmetros, sim...

Mas acho que o problema está aqui:

[color=blue:d3458e9b02]select * from spmax(3, (select max(numemi) from testes2));[/color:d3458e9b02]

Usei este exemplo que vc mesmo me indicou para passar os parâmetros.
Mas observe, no segundo parâmetro:

[color=blue:d3458e9b02]select max(numemi) from testes2[/color:d3458e9b02]

Não está selecionando o codass. Então como ele vai saber que max(numemi) pegar, ou , de quem é o max(numemi)...
Não entendo muito bem, mas acho que nesse select ele está pegando somente o max(numemi) de toda a tabela carass e não o max(numemi) de cada associado.

Sou iniciante em SP, se puder dar uma olhada e colocar suas conclusões, agradeço,

Susana


GOSTEI 0
Martins

Martins

09/04/2006

Oi, Martins, Estou usando IBExpert... Passei os parâmetros, sim... Mas acho que o problema está aqui: [color=blue:e6d8715990]select * from spmax(3, (select max(numemi) from testes2));[/color:e6d8715990] Usei este exemplo que vc mesmo me indicou para passar os parâmetros. Mas observe, no segundo parâmetro: [color=blue:e6d8715990]select max(numemi) from testes2[/color:e6d8715990] Não está selecionando o codass. Então como ele vai saber que max(numemi) pegar, ou , de quem é o max(numemi)... Não entendo muito bem, mas acho que nesse select ele está pegando somente o max(numemi) de toda a tabela carass e não o max(numemi) de cada associado. Sou iniciante em SP, se puder dar uma olhada e colocar suas conclusões, agradeço, Susana


Realmente, sua observação está coerente, é q não tenho como testar esses códigos aqui, pelo menos a solução do colega Motta funcionou perfeitamente, vou ver se através dela podemos chegar a uma SP 100¬ funcional.


GOSTEI 0
Motta

Motta

09/04/2006

A view não é necessária, uma query poderia resolver, mas a view deve solucionar outros problemas envolvendos o último reg. por cliente, sendo reutililizavel vale a pena criar o objeto.


GOSTEI 0
Susi

Susi

09/04/2006

Olá, Martins e Motta,

Martins, obrigada pelo empenho, mas não é necessário ocupar-se com a minha dúvida, visto que o problema foi resolvido e nós temos tanta coisa mais para desenvolver (vida de programador não é facil!!!). Agradeço de coração, talvez em outra oportunidade vc me explique mais um pouco sobre SP.

Motta, é isso mesmo uma query resolve, mas como a minha seleção envolve mais dados e tabelas, a view serviu muito bem... Brigadão...

Um abraço e até mais...

Susana


GOSTEI 0
Martins

Martins

09/04/2006

Olá, Martins e Motta, Martins, obrigada pelo empenho, mas não é necessário ocupar-se com a minha dúvida, visto que o problema foi resolvido e nós temos tanta coisa mais para desenvolver (vida de programador não é facil!!!). Agradeço de coração, talvez em outra oportunidade vc me explique mais um pouco sobre SP. Motta, é isso mesmo uma query resolve, mas como a minha seleção envolve mais dados e tabelas, a view serviu muito bem... Brigadão... Um abraço e até mais... Susana


Ok, tb acho q uma SQL poderia resolver, não testei ainda, mas vou testar com tempo, quanto a uma SP usando a lógica do amigo [b:c1a5c2418a]Motta[/b:c1a5c2418a], poderiamos tentar algo assim.

CREATE PROCEDURE EDMAX (
    PAGAS INTEGER)
RETURNS (
    ID INTEGER,
    CODASS INTEGER,
    EDICAO INTEGER,
    QTPAGAS INTEGER)
AS
begin 
  /* Procedure Text */ 
 for Select id, codass, numemi, qtdpag
  From testes2 t1 where t1.qtdpag >=  agas and t1.numemi >= (select max(t2.numemi) from testes2 t2 where t2.codass = t1.codass)
  into :id, :codass, :edicao, :qtpagas
 do 
  suspend; 
end


e então chamariamos assim:

select * from maxnum where qtdpag >= 3


vc poderia usar tb uma instrução SQL sem a necessidade de uma SP ou View, sendo q as mesmas serviram como exemplos para criação de outras para demais finalidades.

veja essa instrução SQL.
select id, codass, numemi, qtdpag from testes2 t1
where t1.numemi = (select max(t2.numemi) from testes2 t2 where
t2.codass = t1.codass) and qtdpag >= 3


Boa sorte!!!


GOSTEI 0
Martins

Martins

09/04/2006

[color=red:c1b059133c]From testes2 t1 where t1.qtdpag >= agas and t1.numemi >= [/color:c1b059133c]


Corrigindo...

[color=blue:c1b059133c]From testes2 t1 where t1.qtdpag >= :pagas and t1.numemi >= [/color:c1b059133c]



GOSTEI 0
POSTAR