Trazer Registro com data mais atual para cada tipo de produto

04/06/2013

0

Boa Tarde!

Eu não entendo muito de Oracle SQL (nem de SQL nenhum), estou correndo atrás de acordo com as necessidades, e estou com um problema chato aqui! É o seguinte, no banco de dados da empresa existe a tabela onde é registrado a saída de produtos, mas quero que me traga somente 1 registro de cada produto, sendo que, ele seja o mais atual. Exemplo:

Na minha tabela de saída de produtos tem os seguintes registros:
=============================
PRODUTO EMISSÃO

Milho 01/04/2013
Milho 02/04/2013
Milho 05/05/2013
Ervilha 06/03/2013
Ervilha 13/05/2013
Café 22/06/2013
Café 25/05/2013
=============================


Quero que me traga o produto uma única vez, sendo sua data de emissao a mais atual das demais, resultando:
=============================
PRODUTO EMISSÃO

Milho 05/05/2013
Ervilha 13/05/2013
Café 22/06/2013
=============================


Acho que expliquei de uma forma para bom entendimento. Por favor, aguardo qualquer tipo de ajuda!
Lembrando q não sou nenhum expert.


Obrigado!
Mateus Ribeiro

Mateus Ribeiro

Responder

Post mais votado

17/08/2017

Bom dia a todos! Vi verificar o fórum com uma necessidade similar e também fiquei muito desapontado com o sumiço sem compartilhamento de solução de nosso amigo.

"Pesquisando" mais a fundo, e agora compartilhando a informação, encontrei algo que resolveria o problema de unir dados de uma tabela com registros mais recentes de outra tabela.

Abaixo deixarei o link do artigo que me auxiliou. O inglês faz-se necessário. Porém a ideia é simples: você precisa unir a tabela A com os registros mais recentes da tabela B. Então você fará uma consulta que buscará os registros mais recentes na tabela B (usando GROUP BY, conforme já demonstrado em interações anteriores). Porém, como você também precisa das demais colunas, não acaba aqui. O resultado da tabela B (que são os registros mais recentes que você deseja unir com registros de A) você utilizará de INNER JOIN para ligar as tabelas.
Em termos simples e abstraindo muito, você criará uma subconsulta com os dados que você deseja, e fará um JOIN com a tabela desejada para pegar o restante das informações, mas ligando com os registros que efetivamente você precisa.

Abaixo segue o exemplo que me ajudou, e logo abaixo dele, o link do artigo.

Obrigado a todos. O DevMedia é excelente.

SELECT t.Train, t.Dest, r.MaxTime
FROM (
SELECT Train, MAX(Time) as MaxTime
FROM TrainTable
GROUP BY Train
) r
INNER JOIN TrainTable t
ON t.Train = r.Train AND t.Time = r.MaxTime


https://stackoverflow.com/questions/3491329/group-by-with-maxdate

Fabio

Fabio
Responder

Mais Posts

05/06/2013

Carlos Tangerino

Mateus, Bom Dia!

Use o max e o group by como abaixo.

SELECT codigo, MAX(emissao) FROM produto GROUP BY codigo;

Dessa maneira, você seleciona a máxima data de emissão para cada produto seu. O GROUP BY, como o próprio nome diz, agrupa aquilo que se repete.
Se você quiser ordenar a sua consulta, por exemplo, por produto, basta adicionar o ORDER BY.

SELECT codigo, MAX(emissao) FROM produto GROUP BY codigo ORDER BY codigo;

Abraço,
Responder

06/06/2013

Mateus Ribeiro

Mateus, Bom Dia!

Use o max e o group by como abaixo.

SELECT codigo, MAX(emissao) FROM produto GROUP BY codigo;

Dessa maneira, você seleciona a máxima data de emissão para cada produto seu. O GROUP BY, como o próprio nome diz, agrupa aquilo que se repete.
Se você quiser ordenar a sua consulta, por exemplo, por produto, basta adicionar o ORDER BY.

SELECT codigo, MAX(emissao) FROM produto GROUP BY codigo ORDER BY codigo;

Abraço,


Boa Tarde Carlos!

Eu segui sua dica, mas no meu SQL da o seguinte erro:

ORA-00979: não é uma expressão GROUP BY
00979. 00000 - "not a GROUP BY expression"
*Cause:
*Action:
Erro na linha: 1 Coluna: 8

O erro aponta no MAX que to usando no campo Data_Emissao! Fiz o teste usando uma tabela diferente e deu certinho, a diferença é q onde deu certo é uma tabela só! No meu SQL é amarrado muuuitas tabelas, no qual resulta na listagem dos produtos. Isso difere em algo ?

Obrigado!
Responder

07/06/2013

Carlos Tangerino

Bruno, Bom Dia! Na cláusula GROUP BY você tem que citar todos os campos do seu SELECT exceto aquele que você está fazendo o MAX. Provavelmente você tem mais colunas no SELECT e não colocou todas no GROUP BY.

Abraço,
Responder

07/06/2013

Carlos Tangerino

Mateus, me desculpe, inverti seu nome com um de outra dúvida.
Abraço,
Responder

07/06/2013

Mateus Ribeiro

Bruno, Bom Dia! Na cláusula GROUP BY você tem que citar todos os campos do seu SELECT exceto aquele que você está fazendo o MAX. Provavelmente você tem mais colunas no SELECT e não colocou todas no GROUP BY.

Abraço,


Boa Tarde Carlos!

O erro não acusa mais! Porém, os produtos se repetem ainda :/

Meu código é este:

Select Max(n.Data_Emissao), n.Chave_Cliente, c.Nome, (n.NF), i.Descricao_Produto, i.Codigo_Produto, i.Unidade, v.NomeRed, c.CodCli, c.NomeRed as Nome_Fantasia, k.Nome as Contato, c.Fone1 as Telefone, i.Valor_Total

From Notas n, Notas_Itens i, Clientes c, Vendedores v, Contatos k, Produtos p

Where n.Chave = i.Chave_Nota
      and n.Chave_Cliente = c.CodCli
      and p.Codigo = i.Codigo_Produto
      and p.chave_familia= 12 and p.produto= 'SIM' and p.qualidade_critica= 'SIM'
      and n.Data_Emissao <= (Sysdate - 30) and n.Data_Emissao >= (Sysdate - 90)
      and p.chave_familia=12 and p.produto='SIM' and p.qualidade_critica='SIM'
      and c.CodVend = v.CodVendedor
      and c.Contato_Padrao = k.Chave
      and v.Chave_Canal = 12 and v.Inativo = 'NAO'
      and v.CodVendedor = 770
      and c.CodCli = 83955
Group by n.Chave_Cliente, c.Nome, n.NF, i.Descricao_Produto, i.Codigo_Produto, i.Unidade, v.NomeRed, c.CodCli, c.NomeRed, k.Nome, c.Fone1, i.Valor_Total
Order by Codigo_Produto


Será q essa amarração toda entre tabelas não gera algum conflito ?

Obrigado!
Responder

07/06/2013

Carlos Tangerino

Oi Mateus, aparentemente a amarração entre as tabelas está correta. Você tem que se certificar que as chaves que relacionam umas às outras estão na cláusula WHERE. Como eu disse, aparentemente (não conheço a estrutura das suas tabelas) está correto.

Se está repetindo, é porque existe valor diferente em alguma coluna, mesmo sendo a mesma data.

Uma outra solução, já que você quer apenas a máxima data para um determinado produto, independente das outras colunas, faça uma query pra retornar a sua data, ou seja, onde estava "max(n.data_emissao)", troque por uma consulta. Veja também que tirei o GROUP BY, já que não precisa mais:

SELECT (select max(a1.data_emissao) from notas a1 where a1.chave = a.chave) data_emissao,
n.chave_cliente,
c.nome,
(n.nf),
i.descricao_produto,
i.codigo_produto,
i.unidade,
v.nomered,
c.codcli,
c.nomered AS nome_fantasia,
k.nome AS contato,
c.fone1 AS telefone,
i.valor_total
FROM notas n,
notas_itens i,
clientes c,
vendedores v,
contatos k,
produtos p
WHERE n.chave = i.chave_nota
AND n.chave_cliente = c.codcli
AND p.codigo = i.codigo_produto
AND p.chave_familia = 12
AND p.produto = 'SIM'
AND p.qualidade_critica = 'SIM'
AND n.data_emissao <= (SYSDATE - 30)
AND n.data_emissao >= (SYSDATE - 90)
AND p.chave_familia = 12
AND p.produto = 'SIM'
AND p.qualidade_critica = 'SIM'
AND c.codvend = v.codvendedor
AND c.contato_padrao = k.chave
AND v.chave_canal = 12
AND v.inativo = 'NAO'
AND v.codvendedor = 770
AND c.codcli = 83955
ORDER BY codigo_produto;

Espero que agora atenda à sua necessidade...

Abraço,
Responder

17/06/2013

Mateus Ribeiro

Uh' não abandonei o tópico, estava doente... mas ainda estou nesse problema rsrs

Carlos, eu notei que, o GROUP BY só funciona certinho se eu tiver todos os outros registros com valores iguais!

Não sei se me expliquei mto bem, mas acho q estaria faltando alguma coisa... Olha um exemplo de como meu banco de dados está:

(Coloquei numa imagem por que aqui fica tudo desalinhado quando tento desenhar uma tabela rs).

http://img526.imageshack.us/img526/3999/nwxi.jpg

O código que eu tava usando referente a esse exemplo era:

Select UF, NF, CODIGO_PRODUTO, QUANTIDADE, Max(DATA_EMISSAO) as DATA_EMISSAO
From TABELA
Group by UF, NF, CODIGO_PRODUTO, QUANTIDADE


Só que dessa maneira, ele continua repetindo, porém, se eu trocar por:

Select CODIGO_PRODUTO, Max(DATA_EMISSAO) as DATA_EMISSAO
From TABELA
Group by CODIGO_PRODUTO


Ele me traz agrupado certinho, o problema é que eu preciso das outras colunas :(

Grato!
Responder

19/06/2013

Mateus Ribeiro

Carlos, muito obrigado! Com sua dica eu estudei mais a fundo a função, e consegui a solução para essa parte do problema!
Referente a essa questão, o tópico resolveu minha dúvida!


Abraços.
Responder

14/05/2015

Renato Ranzani

Carlos, muito obrigado! Com sua dica eu estudei mais a fundo a função, e consegui a solução para essa parte do problema!
Referente a essa questão, o tópico resolveu minha dúvida!


Abraços.

Mateus, como vc fez com o restante das colunas que precisa também?
Estou com o mesmo problema.
Responder

05/07/2017

Helio Oliveira

Puxa, que egoismo o seu de perguntar, achar a respostar e não compartilhar com os coleguinhas. rsrs
Estou com mesmo problema. =\\
Responder

29/03/2020

César Augusto

Fabio, obrigado pela solução. Foi de grande valia.
Responder

21/12/2022

Lúcio

Bom dia a todos! Vi verificar o fórum com uma necessidade similar e também fiquei muito desapontado com o sumiço sem compartilhamento de solução de nosso amigo.

"Pesquisando" mais a fundo, e agora compartilhando a informação, encontrei algo que resolveria o problema de unir dados de uma tabela com registros mais recentes de outra tabela.

Abaixo deixarei o link do artigo que me auxiliou. O inglês faz-se necessário. Porém a ideia é simples: você precisa unir a tabela A com os registros mais recentes da tabela B. Então você fará uma consulta que buscará os registros mais recentes na tabela B (usando GROUP BY, conforme já demonstrado em interações anteriores). Porém, como você também precisa das demais colunas, não acaba aqui. O resultado da tabela B (que são os registros mais recentes que você deseja unir com registros de A) você utilizará de INNER JOIN para ligar as tabelas.
Em termos simples e abstraindo muito, você criará uma subconsulta com os dados que você deseja, e fará um JOIN com a tabela desejada para pegar o restante das informações, mas ligando com os registros que efetivamente você precisa.

Abaixo segue o exemplo que me ajudou, e logo abaixo dele, o link do artigo.

Obrigado a todos. O DevMedia é excelente.

SELECT t.Train, t.Dest, r.MaxTime
FROM (
SELECT Train, MAX(Time) as MaxTime
FROM TrainTable
GROUP BY Train
) r
INNER JOIN TrainTable t
ON t.Train = r.Train AND t.Time = r.MaxTime


https://stackoverflow.com/questions/3491329/group-by-with-maxdate


--------------------------------------------------------------------------------------------------------------------------------------------------------------
Olá Fábio,
Ainda hoje cinco anos depois, a solução que vc compartilhou continua ajudando outras pessoas.
Me ajudou também. Grato
Responder

22/12/2022

Emerson Nascimento

pode tentar assim também:
SELECT
      p1.*
FROM
      produtos p1
WHERE
      p1.emissao = (select max(p2.emissao) from produtos p2 where p2.produto = p1.produto)

se quiser pesquisar dentro de um intervalo de datas, utilize-a nas duas instruções:
SELECT
      p1.*
FROM
      produtos p1
WHERE
      p1.emissao between DATAINI and DATAFIM
      p1.emissao =
            (select max(p2.emissao) from produtos p2
            where p2.produto = p1.produto and p2.emissao between DATAINI and DATAFIM)


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

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

Aceitar