AJUDA PARA CONSULTA QUE TRAZ MAIOR VALOR DE COMPRAS

30/12/2017

0

Ola amigos, sou novo de SQL Server e precisava muito de uma ajuda, estou tentando montar um a consulta que me traga o valor unitário de uma tabela de cadastro de notas fiscais, porem, traga o valor unitário da ultima compra. Acontece que ele não me traz apenas o item da nota fiscal com a ultima data de entrada, ele esta trazendo com varias datas. Eu preciso apenas do codigo do produto e valor unitario (ultimo de compra). segue a minha query:

SELECT RESULTADO.CODIGO,RESULTADO.UNITARIO,MAX(RESULTADO.EMISSAO) AS EMISSAO
FROM
(SELECT D1_COD AS CODIGO,D1_VUNIT AS UNITARIO,D1_EMISSAO AS EMISSAO
FROM
SD1010
WHERE
D1_TIPO=''N''
AND D1_COD=''NCC00086''
AND D1_NFORI=''''
AND D1_BASEICM>''0''
AND D1_EMISSAO>=''20110101'') AS RESULTADO
GROUP BY RESULTADO.CODIGO,RESULTADO.UNITARIO
Renan

Renan

Responder

Post mais votado

31/12/2017

Renan, a função MAX retorna um valor máximo para o critério, então não é necessário o GROUP BY
No teu caso o que deseja é uma consulta de notas fiscais com o valor máximo naquela data.
SELECT D1_COD AS CODIGO,D1_VUNIT AS UNITARIO,D1_EMISSAO AS EMISSAO, MAX( D1_EMISSAO )
FROM  SD1010 
WHERE 
D1_TIPO='N'
AND D1_COD='NCC00086'
AND D1_NFORI=''
AND D1_BASEICM>'0'
AND D1_EMISSAO>='20110101'


https://docs.microsoft.com/pt-br/sql/t-sql/functions/max-transact-sql

Luiz Vichiatto

Luiz Vichiatto
Responder

Mais Posts

31/12/2017

Renan

Então eu já tentei fazer sem o GROUP BY mas ele não funciona, inclusive executei esse sua query e ele apresenta a seguinte mensagem:
"Msg 8120, Level 16, State 1, Line 2
Column 'SD1010.D1_COD' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Um detalhe, esse produto é comprado varias vezes ao longo do ano, por isso que eu quero apenas trazer o valor da ultima compra registrada na tabela, mas ele trem que trazer esses três campos: código do produto, valor unitário e data de entrada do produto.
Quando eu coloco apenas dois campos na consulta com o group by, ele funciona, mas basta eu colocar mais um campo e ela não funciona.
Como exemplo, essa query aqui funciona, mas se eu acrescentar mais um campo, ele trás vários resultados e não apenas o ultimo:
SELECT
RTRIM(D1_COD) AS CODIGO,
--D1_VUNIT AS VALOR_UNITARIO,
ISNULL(MAX(D1_EMISSAO),0) AS EMISSAO
FROM
SD1010
WHERE D_E_L_E_T_=''
AND D1_TIPO='N'
AND D1_NFORI=''
AND D1_BASEICM>'0'
AND D1_PEDIDO<>''
AND D1_EMISSAO>='20110101'
AND D1_COD='NCC00086'
AND D1_LOCAL IN ('01','16','18')
GROUP BY D1_COD
ORDER BY D1_COD

Meu amigo, muito obrigado pela sua ajuda, fico muito grato!
Responder

31/12/2017

Renan

Então eu já tentei fazer sem o GROUP BY mas ele não funciona, inclusive executei esse sua query e ele apresenta a seguinte mensagem:
"Msg 8120, Level 16, State 1, Line 2
Column 'SD1010.D1_COD' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Um detalhe, esse produto é comprado varias vezes ao longo do ano, por isso que eu quero apenas trazer o valor da ultima compra registrada na tabela, mas ele trem que trazer esses três campos: código do produto, valor unitário e data de entrada do produto.
Quando eu coloco apenas dois campos na consulta com o group by, ele funciona, mas basta eu colocar mais um campo e ela não funciona.
Como exemplo, essa query aqui funciona, mas se eu acrescentar mais um campo, ele trás vários resultados e não apenas o ultimo:
SELECT
RTRIM(D1_COD) AS CODIGO,
--D1_VUNIT AS VALOR_UNITARIO,
ISNULL(MAX(D1_EMISSAO),0) AS EMISSAO
FROM
SD1010
WHERE D_E_L_E_T_=''
AND D1_TIPO='N'
AND D1_NFORI=''
AND D1_BASEICM>'0'
AND D1_PEDIDO<>''
AND D1_EMISSAO>='20110101'
AND D1_COD='NCC00086'
AND D1_LOCAL IN ('01','16','18')
GROUP BY D1_COD
ORDER BY D1_COD

Meu amigo, muito obrigado pela sua ajuda, fico muito grato!
Responder

04/01/2018

Gabriel

bom dia,

Já tentou ordenar a consulta (ORDER BY DESC) em ordem decrescente pela coluna que quer o maior valor.

Caso queira somente um registro limite o resultado a apenas 1 (como select top 1 ou limit 0,1) dependendo do seu banco
Responder

10/01/2018

Luiz Vichiatto

Cada campo que adicionar, tem que colocar no group by.



Então eu já tentei fazer sem o GROUP BY mas ele não funciona, inclusive executei esse sua query e ele apresenta a seguinte mensagem:
"Msg 8120, Level 16, State 1, Line 2
Column 'SD1010.D1_COD' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."

Um detalhe, esse produto é comprado varias vezes ao longo do ano, por isso que eu quero apenas trazer o valor da ultima compra registrada na tabela, mas ele trem que trazer esses três campos: código do produto, valor unitário e data de entrada do produto.
Quando eu coloco apenas dois campos na consulta com o group by, ele funciona, mas basta eu colocar mais um campo e ela não funciona.
Como exemplo, essa query aqui funciona, mas se eu acrescentar mais um campo, ele trás vários resultados e não apenas o ultimo:
SELECT
RTRIM(D1_COD) AS CODIGO,
--D1_VUNIT AS VALOR_UNITARIO,
ISNULL(MAX(D1_EMISSAO),0) AS EMISSAO
FROM
SD1010
WHERE D_E_L_E_T_=''
AND D1_TIPO='N'
AND D1_NFORI=''
AND D1_BASEICM>'0'
AND D1_PEDIDO<>''
AND D1_EMISSAO>='20110101'
AND D1_COD='NCC00086'
AND D1_LOCAL IN ('01','16','18')
GROUP BY D1_COD
ORDER BY D1_COD

Meu amigo, muito obrigado pela sua ajuda, fico muito grato!


Responder

10/01/2018

Emerson Nascimento

Você precisa da 'última compra efetuada' ou da 'última compra de um produto'?

última compra efetuada (podem aparecer vários produtos diferentes):

SELECT * FROM SD1010
WHERE D1_TIPO='N'
AND D1_EMISSAO = (SELECT MAX(D1_EMISSAO) FROM SD1010 WHERE D1_TIPO='N')


última compra de um produto (podem aparecer vários itens do mesmo produto):

SELECT * FROM SD1010
WHERE D1_TIPO = 'N'
AND D1_COD = 'NCC00086'
AND D1_EMISSAO =
(SELECT MAX(D1_EMISSAO) FROM SD1010 WHERE D1_TIPO='N' AND D1_COD = 'NCC00086')

aparentemente você está utilizando o TOTVS Protheus. se estiver, note que você precisa observar também o TES para determinar se é uma compra ou UM retorno de beneficiamento. também pode ser útil avaliar se está gerando duplicata, o que pode confirmar a compra.

note também que, no caso do Protheus, o campo D1_EMISSAO indica a data de emissão da nota pelo fornecedor.
talvez para a sua análise seja melhor observar o campo D1_DTDIGIT, que indica o dia que a nota entrou na empresa.

além disso, é preciso observar que você deve incluir os campos D_E_L_E_T_ e D1_FILIAL nas condições das consultas - aliás, sempre mencione os campos D_E_L_E_T_ e xx_FILIAL.
Responder

18/01/2018

Renan

Emerson, obrigado pela sua resposta e eu estou atento para estes campos que você mencionou, apenas simplifiquei a consulta para não ficar grande o post, mas agradeço muito pela sua atenção com o assunto.

Eu preciso apenas que ele me traga a ultima compra daquele determinado código, seria exatamente esse retorno que a sua ultima consulta apresenta:

SELECT * FROM SD1010
WHERE D1_TIPO = 'N'
AND D1_COD = 'NCC00086'
AND D1_EMISSAO =
(SELECT MAX(D1_EMISSAO) FROM SD1010 WHERE D1_TIPO='N' AND D1_COD = 'NCC00086')

,no entanto, preciso que traga todos os meus códigos da tabela de produtos ao executar a consulta, e essa sua sugestão, apresenta apenas para um único código, ou seja, o código que eu especificar na Query. Seria possível ele trazer toda a tabela apresentando apenas um único código por linha?

Nesta Query ele repete os resultados por código varias vezes, não trás apenas o valor unitário da ultima compra apenas uma vez código por código:

SELECT
RTRIM(D1_COD) AS CODIGO,
D1_VUNIT AS VALOR_UNITARIO,
CAST(ISNULL(MAX(D1_DTDIGIT),0) AS date) AS EMISSAO
FROM
SD1010
WHERE D_E_L_E_T_=''
AND D1_TIPO='N'
--AND D1_COD='G256282' --(AQUI EU DETERMINEI O CÓDIGO, MAS GEREI A CONSULTA COM ESSA LINHA COMENTADA)
AND D1_NFORI=''
AND D1_TES='223'
AND D1_BASEICM>'0'
AND D1_PEDIDO<>''
AND D1_DTDIGIT>='20110101'
AND D1_FILIAL='01'
AND D1_LOCAL IN ('01','16','18')
GROUP BY D1_COD,D1_VUNIT
ORDER BY D1_COD

OLHA O RESULTADO:
CODIGO - VALOR_UNITARIO - EMISSAO
G256282 - R$ 1.513,88 - 23/07/2014
G256282 - R$ 2.230,00 - 07/05/2015
G256282 - R$ 2.416,81 - 03/06/2016
G256282 - R$ 3.298,73 - 11/02/2016


Obrigado!!

Responder

18/01/2018

Renan

Respondi abaixo do seu post Emerson, Obrigado!!
Responder

19/01/2018

Emerson Nascimento

Renan, há várias formas de fazer o que você precisa. Uma delas é esta abaixo:

SELECT B1.B1_COD, B1.B1_TIPO, B1.B1_DESC,
COALESCE(D1.D1_EMISSAO,'') EMISSAO,
COALESCE(D1.D1_VUNIT,0) VUNIT
FROM SB1010 B1
LEFT JOIN
(SELECT D1_COD, MAX(D1_EMISSAO) EMISSAO FROM SD1010
WHERE D_E_L_E_T_ = '' AND D1_FILIAL = ''
AND D1_TIPO = 'N'
GROUP BY D1_COD) D ON D.D1_COD = B1.B1_COD
LEFT JOIN SD1010 D1 ON D1.D_E_L_E_T_ = '' AND D1.D1_FILIAL = ''
AND D1.D1_TIPO = 'N'
AND D1.D1_EMISSAO = D.EMISSAO
AND D1.D1_COD = D.D1_COD
WHERE B1.D_E_L_E_T_ = '' AND B1.B1_FILIAL = ''
-- AND B1.B1_COD = 'NCC00086'
ORDER BY B1.B1_COD

Note que a pesquisa parte da tabela SB1, logo todos o produtos serão avaliados.

Para melhorar a performance, crie um índice na tabela SD1 pelos campos D1_FILIAL + D1_TIPO + D1_COD + D1_EMISSAO.
Se você não tiver o índice, execute a query sem o índice e depois execute novamente com o índice criado; compare o tempo de cada uma delas e você verá que há uma enorme diferença.
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