Agrupando a quantidade de Bens no mesmo Documento de Financiamento

SQL

21/08/2023

Olá
Tenho 3 tabelas relacionadas
1 tabela FinanciamentoBem
Campos:
OidFinancimaentoBem
OidDocumento
OidBem

2 Tabela FinanciamentoMov
Campos:
OidfinancimentoMov
OidDocumento
DtVencimento
ValorJurosMes

3 tabela vEquipamentoIdentificacao
OidBem
Identificacao

Na tabela FinanciamentoMov consta todos os bens que possuem financiamento e cada OidDocumento possui um ou mas bens no mesmo documento, preciso quantificar quantos bens estão no mesmo OidDocumento, após identificar o numero de bens no mesmo OidDocumento tenho que pegar o valorJurosMes e dividir pelo numero de bens encontrando o valor de parcela de cada bem.

Esse código me retorna a quantidade de OIDFinanciamentoBem mas quando incluo os campos OidBem, Identificacao no GROUP BY os valores de agregação ficam individuais

SELECT DISTINCT
COUNT(OIDFinanciamentoBem)Numero,
FinanciamentoMov.OIDDocumento,
ValorJurosMes/COUNT(DISTINCT FinanciamentoBem.OIDBem)as parcela,
DtVencimento
FROM FinanciamentoMov
INNER JOIN FinanciamentoBem
ON FinanciamentoBem.OIDDocumento = FinanciamentoMov.OIDDocumento
INNER JOIN vEquipamentoSomenteIdentificacao
on FinanciamentoBem.OIDBem = vEquipamentoSomenteIdentificacao.OIDBem
WHERE FinanciamentoMov.OIDDocumento = FinanciamentoMov.OIDDocumento AND DtVencimento BETWEEN ''''2023/01/01'''' AND GETDATE ()
GROUP BY
FinanciamentoMov.OIDDocumento,
ValorJurosMes,
DtVencimento
Adriano Anacleto

Adriano Anacleto

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

22/08/2023

você não pode incluir um campo que "individualiza" o registro. se fizer, o GROUP BY não faz sentido.
seria o mesmo que agrupar um cadastro de clientes por CPF sabendo que o CPF é único.

tente algo assim:
SELECT
	FM.OIDDocumento documento,
	FM.ValorJurosMes valor,
	COUNT(FB.OIDBem) qtditens,
	FM.ValorJurosMes / COUNT(FB.OIDBem) parcela
FROM
	FinanciamentoMov FM
INNER JOIN
	FinanciamentoBem FB
	ON
	FB.OIDDocumento = FM.OIDDocumento
WHERE
	FM.DtVencimento BETWEEN '2023/01/01' AND GETDATE ()
GROUP BY
	FM.OIDDocumento,
	FM.ValorJurosMes
não faz sentido ter DISTINCT e GROUP BY na mesma consulta.
a tabela vEquipamentoSomenteIdentificacao não tem relevância na consulta; não precisa dela.

GOSTEI 1

Mais Respostas

Adriano Anacleto

Adriano Anacleto

21/08/2023

você não pode incluir um campo que "individualiza" o registro. se fizer, o GROUP BY não faz sentido.
seria o mesmo que agrupar um cadastro de clientes por CPF sabendo que o CPF é único.

tente algo assim:
SELECT
	FM.OIDDocumento documento,
	FM.ValorJurosMes valor,
	COUNT(FB.OIDBem) qtditens,
	FM.ValorJurosMes / COUNT(FB.OIDBem) parcela
FROM
	FinanciamentoMov FM
INNER JOIN
	FinanciamentoBem FB
	ON
	FB.OIDDocumento = FM.OIDDocumento
WHERE
	FM.DtVencimento BETWEEN '2023/01/01' AND GETDATE ()
GROUP BY
	FM.OIDDocumento,
	FM.ValorJurosMes
não faz sentido ter DISTINCT e GROUP BY na mesma consulta.
a tabela vEquipamentoSomenteIdentificacao não tem relevância na consulta; não precisa dela.


Olá Emerson Nascimento,
Fico muito feliz pela sua interação e intenção de me auxiliar, sou novo nessa área, mas vamos lá, o resultado que espero alcançar é o seguinte:
dentro do desse contexto preciso extrair:
OidBem, DtVencimento, Parcela, ou seja, a sua consulta me apresenta o valor esperado da parcela então preciso trazer esse valor da parcela para cada OidBem entendeu?
estou criando essa consulta para contabilizar o custo para cada OidBem, entendo que seria o mesmo que agrupar um cadastro de clientes por CPF sabendo que o CPF é único mas digamos que eu e vc fizessem um financiamento juntos em um contrato de financiamento e que nesse contrato estivesse vinculado os dois CPF a parcela desse financiamento seria dividido por 2, seria +- isso que ocorre com os financiamentos dos OidBens onde temos vários OidBens dentro do mesmo contrato de financiamento e o valorJurosMes deve ser dividido pelo numero de OidBem que possui no OidDocumento.
Essa seria a minha dificuldade, eu não encontrei uma logica dentro desse contexto mas imagino que devo criar uma subselect para quantificar o numero de OIDBem no mesmo OIDDocumento esse valor levar para ou outro select que não altere o contexto da consulta..
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

21/08/2023

SELECT
  COUNT(OIDFinanciamentoBem) Numero,
  FinanciamentoMov.OIDDocumento,
  ValorJurosMes/( COUNT(DISTINCT FinanciamentoBem.OIDBem) over(partition by FinanciamentoBem.OIDDocumento) ) as parcela,
  DtVencimento
FROM
  FinanciamentoMov
    INNER JOIN FinanciamentoBem
      ON FinanciamentoBem.OIDDocumento = FinanciamentoMov.OIDDocumento
    INNER JOIN vEquipamentoSomenteIdentificacao
      on vEquipamentoSomenteIdentificacao.OIDBem = FinanciamentoBem.OIDBem
WHERE
  DtVencimento BETWEEN ''''2023/01/01'''' AND GETDATE ()
GROUP BY
  FinanciamentoMov.OIDDocumento, ValorJurosMes, DtVencimento

GOSTEI 1
Adriano Anacleto

Adriano Anacleto

21/08/2023

SELECT
  COUNT(OIDFinanciamentoBem) Numero,
  FinanciamentoMov.OIDDocumento,
  ValorJurosMes/( COUNT(DISTINCT FinanciamentoBem.OIDBem) over(partition by FinanciamentoBem.OIDDocumento) ) as parcela,
  DtVencimento
FROM
  FinanciamentoMov
    INNER JOIN FinanciamentoBem
      ON FinanciamentoBem.OIDDocumento = FinanciamentoMov.OIDDocumento
    INNER JOIN vEquipamentoSomenteIdentificacao
      on vEquipamentoSomenteIdentificacao.OIDBem = FinanciamentoBem.OIDBem
WHERE
  DtVencimento BETWEEN ''''2023/01/01'''' AND GETDATE ()
GROUP BY
  FinanciamentoMov.OIDDocumento, ValorJurosMes, DtVencimento


Olá Arthur Heinrich
tentei compilar o código e gerou erro 3 Incorrect syntax near 'distinct'. G:\\Consultas SQL\\SQL1.sql__.sql 214 22
SELECT
SELECT
COUNT (FB.OIDFinanciamentoBem) numero,
FB.OIDDocumento,
ValorJurosMes/(COUNT(DISTINCT FB.OIDBem) OVER (PARTITION BY FinanciamentoBem.OIDDocumento)) as parcela,
FM.DtVencimento
FROM FinanciamentoMov FM
INNER JOIN FinanciamentoBem FB
ON FB.OIDDocumento= FM.OIDDocumento
INNER JOIN vEquipamentoSomenteIdentificacao
ON FB.OIDBem = vEquipamentoSomenteIdentificacao.OIDBem
WHERE
FM.DtVencimento BETWEEN '2023/01/01' AND GETDATE ()
GROUP BY
FB.OIDDocumento,FM.ValorJurosMes,FM.DtVencimento

GOSTEI 0
Arthur Heinrich

Arthur Heinrich

21/08/2023

O uso da cláusula over() transforma a função agregadora em uma função analítica.

(COUNT(DISTINCT FB.OIDBem) OVER (PARTITION BY FinanciamentoBem.OIDDocumento)

Pode ser que o banco não saiba interpretar count(distinct xxx) em uma função analítica. Experimente sem o distinct, mas o resultado pode ficar diferente, dependendo dos seus bens.

Imagine que seu documento tem 3 bens: 1, 2 e 2.

Com o distinct, o count retornaria 2. Sem o distinct pode retornar 3.

Aliás, pensando nisso, vejo que sua query pode ter um erro.

Imagine que existam 3 bens, com valor total de R$ 900,00. Sendo R$ 300 de cada um.

Se utilizar o distinct, o resultado diria que a parcela é R$ 450,00. Se não usar, dirá que é R$ 300,00.
GOSTEI 1
Emerson Nascimento

Emerson Nascimento

21/08/2023

uma possível solução:
SELECT
	FB.OidDocumento,
	FB.OidBem,
	IT.DtVencimento,
	ROUND(IT.ValorJurosMes / IT.Itens,3) parcela
FROM
	FinanciamentoBem FB
INNER JOIN
	(	SELECT T1.OidDocumento, T2.ValorJurosMes, T2.DtVencimento, COUNT(T1.OidBem) Itens
		FROM FinanciamentoBem T1
		INNER JOIN FinanciamentoMov T2 ON T2.OidDocumento = T1.OidDocumento
		WHERE T2.DtVencimento BETWEEN '2023/01/01' AND GETDATE ()
		GROUP BY T1.OidDocumento, T2.DtVencimento, T2.ValorJurosMes) IT
	ON
	IT.OidDocumento = FB.OidDocumento
GOSTEI 1
Adriano Anacleto

Adriano Anacleto

21/08/2023

uma possível solução:
SELECT
	FB.OidDocumento,
	FB.OidBem,
	IT.DtVencimento,
	ROUND(IT.ValorJurosMes / IT.Itens,3) parcela
FROM
	FinanciamentoBem FB
INNER JOIN
	(	SELECT T1.OidDocumento, T2.ValorJurosMes, T2.DtVencimento, COUNT(T1.OidBem) Itens
		FROM FinanciamentoBem T1
		INNER JOIN FinanciamentoMov T2 ON T2.OidDocumento = T1.OidDocumento
		WHERE T2.DtVencimento BETWEEN ''2023/01/01'' AND GETDATE ()
		GROUP BY T1.OidDocumento, T2.DtVencimento, T2.ValorJurosMes) IT
	ON
	IT.OidDocumento = FB.OidDocumento


Olá Emerson Nascimento,
Maravilha, a principio ficou perfeito sua consulta.
Agradecido pelos seus auxílios!
Abraço!
GOSTEI 0
Adriano Anacleto

Adriano Anacleto

21/08/2023

O uso da cláusula over() transforma a função agregadora em uma função analítica.

(COUNT(DISTINCT FB.OIDBem) OVER (PARTITION BY FinanciamentoBem.OIDDocumento)

Pode ser que o banco não saiba interpretar count(distinct xxx) em uma função analítica. Experimente sem o distinct, mas o resultado pode ficar diferente, dependendo dos seus bens.

Imagine que seu documento tem 3 bens: 1, 2 e 2.

Com o distinct, o count retornaria 2. Sem o distinct pode retornar 3.

Aliás, pensando nisso, vejo que sua query pode ter um erro.

Imagine que existam 3 bens, com valor total de R$ 900,00. Sendo R$ 300 de cada um.

Se utilizar o distinct, o resultado diria que a parcela é R$ 450,00. Se não usar, dirá que é R$ 300,00.


Olá Arthur Heinrich,
Agradeço pelo seus auxílios mas fiz as alterações de retirar o Distinct na estrutura e não rodou gerou erro.

SELECT
COUNT (FB.OIDFinanciamentoBem) numero,
FM.OIDDocumento,
ValorJurosMes/(COUNT(FB.OIDBem) OVER (PARTITION BY FB.OIDDocumento)) as parcela,
FM.DtVencimento
FROM FinanciamentoMov FM
INNER JOIN FinanciamentoBem FB
ON FB.OIDDocumento= FM.OIDDocumento
INNER JOIN vEquipamentoSomenteIdentificacao
ON FB.OIDBem = vEquipamentoSomenteIdentificacao.OIDBem
WHERE
FM.DtVencimento BETWEEN '2023/01/01' AND GETDATE ()
GROUP BY
FM.OIDDocumento,FM.ValorJurosMes,FM.DtVencimento

1 Column 'FinanciamentoBem.OIDDocumento' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. G:\\Consultas SQL\\SQL1.sql__.sql 211 1
GOSTEI 0
POSTAR