Trazer Registro com data mais atual para cada tipo de produto
04/06/2013
0
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
Post mais votado
17/08/2017
"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
Mais Posts
05/06/2013
Carlos Tangerino
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,
06/06/2013
Mateus Ribeiro
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!
07/06/2013
Carlos Tangerino
Abraço,
07/06/2013
Carlos Tangerino
Abraço,
07/06/2013
Mateus Ribeiro
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!
07/06/2013
Carlos Tangerino
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,
17/06/2013
Mateus Ribeiro
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!
19/06/2013
Mateus Ribeiro
Referente a essa questão, o tópico resolveu minha dúvida!
Abraços.
14/05/2015
Renato Ranzani
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.
05/07/2017
Helio Oliveira
Estou com mesmo problema. =\\
21/12/2022
Lúcio
"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
22/12/2022
Emerson Nascimento
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)
Clique aqui para fazer login e interagir na Comunidade :)