Trazer Registro com data mais atual para cada tipo de produto
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!
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
Curtidas 1
Melhor post
Fabio
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
"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
GOSTEI 3
Mais Respostas
Carlos Tangerino
04/06/2013
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,
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,
GOSTEI 2
Mateus Ribeiro
04/06/2013
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,
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!
GOSTEI 0
Carlos Tangerino
04/06/2013
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,
Abraço,
GOSTEI 1
Carlos Tangerino
04/06/2013
Mateus, me desculpe, inverti seu nome com um de outra dúvida.
Abraço,
Abraço,
GOSTEI 0
Mateus Ribeiro
04/06/2013
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,
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!
GOSTEI 0
Carlos Tangerino
04/06/2013
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,
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,
GOSTEI 0
Mateus Ribeiro
04/06/2013
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:
Só que dessa maneira, ele continua repetindo, porém, se eu trocar por:
Ele me traz agrupado certinho, o problema é que eu preciso das outras colunas :(
Grato!
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!
GOSTEI 0
Mateus Ribeiro
04/06/2013
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.
Referente a essa questão, o tópico resolveu minha dúvida!
Abraços.
GOSTEI 0
Renato Ranzani
04/06/2013
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.
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.
GOSTEI 0
Helio Oliveira
04/06/2013
Puxa, que egoismo o seu de perguntar, achar a respostar e não compartilhar com os coleguinhas. rsrs
Estou com mesmo problema. =\\
Estou com mesmo problema. =\\
GOSTEI 0
César Augusto
04/06/2013
Fabio, obrigado pela solução. Foi de grande valia.
GOSTEI 0
Lúcio
04/06/2013
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
"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
GOSTEI 0
Emerson Nascimento
04/06/2013
pode tentar assim também:
se quiser pesquisar dentro de um intervalo de datas, utilize-a nas duas instruções:
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)
GOSTEI 0