Select trazendo somente registros da última data

28/08/2018

0

Bom dia pessoal do forum.
Estou me batendo com uma consulta com tabela referenciada, onde devo trazer somente 1 vez um material, carregando o valor dele baseado na última data de atualização dele. Adicionalmente tenho uma cláusula que diz que a data tem que ser diferente de 1o de agosto. Ou seja, quero o material, valor e data de atualização dele(imediatamente anterior a 01/08/2018).
Na tabela cl_conveniomaterialvalores tenho os códigos, que referencio o nome na tabela cl_material para trazer o nome por escrito, assim como referencio o código que está na tabela cl_conveniomaterialvalores com a referência na cl_convenios Então são três tabelas, 1 com os dados e as outras duas como referência (somente para trazer o nome ao invés do código)
O que estou tentando é o seguinte:

select max(A.data) as ULTIMAATUALIZACAO, B.nome, A.valor, C.nome as CONVENIO
from cl_conveniomaterialvalores as A, cl_materiais as B, cl_convenios as C
where A.convenio=C.handle and B.handle=A.material and A.data < '01.08.2018 00:00'
group by B.nome, a.valor, c.nome
order by max(a.data) desc

Porém não estou obtendo somente a última data, o material tem aparecido repetido, com datas diferentes.
Exemplo: de 1 material
Caneta
Datas de atualizacao: 01/08/2018, 06/05/2018, 20/03/2018
Eu queria trazer somente o resultado: Caneta - 06/05/2018, porém os resultados abaixo também tem aparecido.

Alguém tem alguma luz??
Obrigado
Diego

Diego

Responder

Post mais votado

28/08/2018

Equivoco meu, não percebi que o banco era firebird.

Qdo eu utilizava firebird, aquela forma que vc utilizou era mais performatico que o left join.

Mas acredito que o ideal para vc seria utilizar um subselect provavalmente.

Não sei como é o comportamento do firebird com subselects, em relação a performance e tal.

Mas basicamente a subselect vai funcionar igual o outer apply, ai vc colocar um top 1 ou first 1, nao me lembro qual eh no firebird, e um oder by desc pela data e ele vai trazer o ultimo registro que vc quer.

Imagino que ja resolva seu problema.

Se vc precisar de ultimo valor pago e ultima data, provavelmente deverá utilizar dois subselects.

Siga basicamente a mesma ideia do outer apply do exemplo que dei.

Mas vou dar uma olhada e ver se consigo montar um codigo e posto aqui para vc.

Atenciosamente,

Alex Lekao

Alex Lekao
Responder

Mais Posts

28/08/2018

Diego

Também tentei usando o having<br />
select distinct max(A.data) as ULTIMAATUALIZACAO, B.nome, A.valor, C.nome as CONVENIO<br />
from cl_conveniomaterialvalores as A, cl_materiais as B, cl_convenios as C<br />
where A.convenio=C.handle and B.handle=A.material<br />
group by B.nome, a.valor, c.nome<br />
having max(A.data) < ''01.08.2018 00:00''<br />
order by max(a.data) desc<br />
<br />
Se eu coloco > que 01.08.2018 ele lista também, as datas acima, porém, não só a última, e sim todas ocorrências acima de 01.08, como 02,03,etc...
Responder

28/08/2018

Alex Lekao

Ola Diego, bom dia!!!

Não sei se entendi bem.

Eu normalmente faço este tipo de referência, utilizando uma subselect para trazer apenas as datas que eu preciso.

Uma boa opção é utilizar o outer apply, com ele vc conseguira trazer mais de um resultado do que vc precisa; como por exemplo, ultima data, ultimo preco, etc., mas tudo dependerá de testes e tal.

Experimete assim e veja se funciona.

select 
   max(A.data) as ULTIMAATUALIZACAO, 
   mat.nome, 
   A.valor, 
   cv.nome as CONVENIO
from cl_conveniomaterialvalores as A, cl_convenios as C
outer apply (select
                         b.*
		      from cl_materiais as b
		      where b.handle = a.material) mat
outer apply (select
                         c.*
		      from cl_convenio as c
		      where c.handle = a.convenio) cv
where A.data < '01.08.2018 00:00'
group by mat.nome, a.valor, cv.nome
order by max(a.data) desc


normalmente não utilizo referenciar tabelas assim "from cl_conveniomaterialvalores as A, cl_materiais as B, cl_convenios as C", nos meus scripts tenho a impressão que é performático, vc pode substituir por left join por exemplo, ou o outer apply, algumas vezes o outer apply eh mais performático que o left join, mas ai tem que testar e ver o que melhor se encaixa com o seu script.

espero ter ajudado.

Atenciosamente,
Responder

28/08/2018

Diego

Olá Alex! Muito obrigado pela resposta!
Então: Basicamente que quero é listar a maior data de atualização de valor do produto (abaixo do dia 01;08), trazendo essa data, esse produto, o valor, e qual convênio ele pertence.
O outer apply não é suportado pelo Firebird.... Então substitui pelo LEFT JOIN, ficando assim
select
max(A.data) as ULTIMAATUALIZACAO,
mat.nome,
A.valor,
cv.nome as CONVENIO
from cl_conveniomaterialvalores as A, cl_convenios as C
left JOIN (select
b.*
from cl_materiais as b
where b.handle = a.material) mat
left JOIN (select
c.*
from cl_convenio as c
where c.handle = a.convenio) cv
where A.data < '01.08.2018 00:00'
group by mat.nome, a.valor, cv.nome
order by max(a.data) desc

Porém está dando erro no where após atribuir aquele left join como cv

SQL error code = -104.
Token unknown - line 15, column 1.
where.
Responder

28/08/2018

Diego

Olá Alex.
Muito obrigado pelo retorno e atenção. A performance não seria preocupação nesse momento, uma vez que eu devo gerar esse relatório uma única vez. Vou tentando aqui baseado no que você sugeriu. De qualquer forma, se conseguir montar um código ficaria ainda melhor hehe. Abraços

Responder

28/08/2018

Alex Lekao

Experimente esse exemplo.

Basicamente para vc ter uma ideia mesmo.

select
   mat.nome,
   (select
       first 1 a.data
	from cl_conveniomaterialvalores as a
	where a.convenio = mat.handle
	orde by a.data desc) as ultdata,
	(select
	    
	 from cl_convenio as cv
	 where cv.convenio = mat.handle
	 order by cv.data desc) as maxpreco
from cl_materiais as mat
group by mat.nome, a.valor, cv.nome


Atenciosamente,
Responder

28/08/2018

Diego

Olá Alex.
No segundo Select, que campo você quis ler? Está assim:
(select

from cl_convenio as cv
Seria o nome?
Responder

28/08/2018

Alex Lekao

hahaha

era preco.

esqueci de colocar, eh que eu monto a estrutura do from primeiro, depois eu relaciono os campos, que o SGDB indica os campos da tabela, fica mais facil, nao preciso lembrar os campo da tabela. rsrsr

Responder

28/08/2018

Emerson Nascimento

Diego, acredito que você precisa de algo assim:
select
   mat.nome,
   cmv.valor,
   cmv.data as ULTIMAATUALIZACAO,
   cv.nome as CONVENIO
from
   cl_materiais as mat
left join
   (select material, max(data) as ultdata
    from cl_conveniomaterialvalores
    where data < '01-08-2018'
    group by material) ult on ult.material = mat.handle
left join
    cl_conveniomaterialvalores as cmv on cmv.material = mat.handle
    and cmv.data = ult.data
left join
    cl_convenio as cv on cv.handle = cmv.convenio


ou assim:
select
   mat.nome,
   cmv.valor,
   cmv.data as ULTIMAATUALIZACAO,
   cv.nome as CONVENIO
from
   cl_materiais as mat
left join
   (select material, convenio, max(data) as ultdata
    from cl_conveniomaterialvalores
    where data < '01-08-2018'
    group by material, convenio) ult on ult.material = mat.handle
left join
    cl_conveniomaterialvalores as cmv on cmv.material = mat.handle
    and cmv.convenio = ult.convenio
    and cmv.data = ult.data
left join
    cl_convenio as cv on cv.handle = cmv.convenio
Responder

29/08/2018

Diego

Olá ALex!
Muito obrigado pela atenção... No fim das contas consegui fazer com um simples subselect, como você havia sugerido anteriormente...
SELECT a.DATA, a.valor, a.material,b.nome, c.nome as convenio
FROM CL_CONVENIOMATERIALVALORES a, cl_convenios c, cl_materiais b
 WHERE a.DATA =
    (SELECT max(data) FROM CL_CONVENIOMATERIALVALORES WHERE material=a.material) AND a.convenio=c.handle AND a.material=b.handle AND a.DATA < '01.08.2018 00:00' 


Bastou fazer o subselect no where para conseguir os resultados...
Obrigado e abraços....
Responder

29/08/2018

Alex Lekao

Oi Diego, boa tarde!!!

Que bom que deu certo e pude ajudar.

Qqr coisa, estamos ai.

Eu soubendo de algo, compartilho.

Atenciosamente,
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar