Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

port3r

[Resolvido] Agrupamento (Group by) em sequência quebrada

Recommended Posts

Pessoal, necessito da ajuda de vocês para bolar um algoritmo que faça o seguinte:

 

Simulação dos campos da tabela.

 

CAMPOS:

======

NUMNOTA

DTNEGOCIACAO

VLRNOTA

 

VALORES PARA OS CAMPOS:

===================

 

NUMNOTA || DTNEGOCIACAO || VLRNOTA

210111 || 01/01/2009 || 10.00

210112 || 01/01/2009 || 20.00

210113 || 07/01/2009 || 30.00

210220 || 10/01/2009 || 15.00

210221 || 13/01/2009 || 25.00

210222 || 27/01/2009 || 35.00

210223 || 27/01/2009 || 45.00

210515 || 30/01/2009 || 70.00

 

Se vocês observarem, o campo NUMNOTA possui uma sequência de valores, que em alguns casos é quebrada. Por exemplo, do NUMNOTA 210114 ao NUMNOTA 210119 não existe.

 

Estou quebrando a cabeça para criar uma função, que retorne a primeira e última nota, agrupando o valor que as compreendem, até a sequencia quebrar.

O return da função seria como segue abaixo:

 

NUMOTA: 210111 à 210113 - DTNEGOCIACAO: 01/01/2009 a 07/01/2009 - VLRNOTA: 60.00

NUMOTA: 210220 à 210223 - DTNEGOCIACAO: 10/01/2009 a 27/01/2009 - VLRNOTA: 120.00

NUMOTA: 210515 à 210515 - DTNEGOCIACAO: 30/01/2009 a 30/01/2009 - VLRNOTA: 70.00

 

O importante não é a menor e maior DTNEGOCIACAO e sim a sequência do campo NUMNOTA.

 

Se alguém já possuir tal algoritmo em qualquer linguagem, eu transformo para PL/SQL.

 

 

Muito obrigado.

Humberto

Compartilhar este post


Link para o post
Compartilhar em outros sites

Saiu um artigo na revista SQLMaganize a um tempo atrás com algo parecido , usando aqueles funções do Oracle para agrupamento

 

tipo rank , dense rank etc.

 

Juntando tabelas virtuais e funções tipo max e min

 

Não sei o número mas fazia algo parecido com o que se quer aqui.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Consegui!

 

Isso é um cursor que exibe os resultados via DBMS_OUTPUT. Ou seja, pra você fazer a saída dele de outra forma terá que adaptar o código à liguagem que você vai usar.

 

Segue abaixo:

 

Declare

  Numnf Number;
  Minnf Number;
  Msg1  Varchar2(150);
  Msg2  Varchar2(150);
  Msg3  Varchar2(150);

Begin

  Select Min(a.Nrnota)
	Into Numnf
	From Fatura a
   Where a.periodo = 122008
	 And a.Nrnota Is Not Null
   Order By a.Nrnota;

  For x In (Select f.Nrnota
			  From Fatura f
			 Where f.periodo = 122008
			   And f.Nrnota Is Not Null
			 Order By f.Nrnota) Loop
  
	If x.Nrnota > Numnf Then
	  Begin
	  
		Select 'NUM NOTA: ' || Min(z.Nrnota) || ' a ' ||
			   Max(z.Nrnota),
			   'DATA NEGOCIACAO: ' || Min(z.Dtemissao) || ' a ' ||
			   Max(z.Dtemissao),
			   'VALOR NOTA: ' || Sum(z.Vltotal)
		  Into Msg1, Msg2, Msg3
		  From Fatura z
		 Where z.periodo = &Periodo
		   And z.Nrnota Is Not Null
		   And z.Nrnota Between Nvl(Minnf, 0) And Numnf;
	  
		Dbms_Output.Put_Line(Msg1 || ' - ' || Msg2 || ' - ' || Msg3);
	  
		Numnf := x.Nrnota;
		Minnf := x.Nrnota;
	  
	  End;
	End If;
  
	Numnf := Numnf + 1;
  
  End Loop;

End;

No meu DBMS aqui saiu exatamente os 'furos' que existem na numeração sequencial dessa massa de dados que eu tenho aqui, como segue:

 

NUM NOTA: 54752 a 56029 - DATA NEGOCIACAO: 01/12/2008 a 01/12/2008 - VALOR NOTA: 5634124.2

NUM NOTA: 56068 a 56068 - DATA NEGOCIACAO: 01/12/2008 a 01/12/2008 - VALOR NOTA: 75952

NUM NOTA: 56070 a 56070 - DATA NEGOCIACAO: 01/12/2008 a 01/12/2008 - VALOR NOTA: 18996.08

NUM NOTA: 56072 a 56082 - DATA NEGOCIACAO: 01/12/2008 a 01/12/2008 - VALOR NOTA: 105554.66

NUM NOTA: 56084 a 56144 - DATA NEGOCIACAO: 01/12/2008 a 02/12/2008 - VALOR NOTA: 479243.59

NUM NOTA: 56424 a 56424 - DATA NEGOCIACAO: 03/12/2008 a 03/12/2008 - VALOR NOTA: 3950.68

NUM NOTA: 56435 a 56435 - DATA NEGOCIACAO: 03/12/2008 a 03/12/2008 - VALOR NOTA: 1745.23

NUM NOTA: 56438 a 56439 - DATA NEGOCIACAO: 03/12/2008 a 03/12/2008 - VALOR NOTA: 6895.15

NUM NOTA: 56571 a 56576 - DATA NEGOCIACAO: 08/12/2008 a 08/12/2008 - VALOR NOTA: 116393.51

NUM NOTA: 56580 a 56580 - DATA NEGOCIACAO: 08/12/2008 a 08/12/2008 - VALOR NOTA: 922.99

NUM NOTA: 57121 a 57333 - DATA NEGOCIACAO: 05/12/2008 a 15/12/2008 - VALOR NOTA: 1153755.02

NUM NOTA: 57335 a 57498 - DATA NEGOCIACAO: 11/12/2008 a 15/12/2008 - VALOR NOTA: 882242.1

NUM NOTA: 57500 a 57671 - DATA NEGOCIACAO: 15/12/2008 a 23/12/2008 - VALOR NOTA: 671848.18

NUM NOTA: 59005 a 59009 - DATA NEGOCIACAO: 20/12/2008 a 20/12/2008 - VALOR NOTA: 40489.03

NUM NOTA: 59016 a 59150 - DATA NEGOCIACAO: 20/12/2008 a 21/12/2008 - VALOR NOTA: 744583.26

NUM NOTA: 59153 a 59205 - DATA NEGOCIACAO: 21/12/2008 a 22/12/2008 - VALOR NOTA: 34617.68

NUM NOTA: 59210 a 59553 - DATA NEGOCIACAO: 24/12/2008 a 28/12/2008 - VALOR NOTA: 1628768.15

 

 

Espero que isso ajude em alguma coisa, hehehehehe

Abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Motta, obrigado pela dica do artigo, vou procurar no site o número da revista e tentar comprar a mesma, até mesmo para repositório.

 

André Renato, parabéns! O resultado é este mesmo.

 

Eu também consegui o resultado que esperava, a lógica ficou bem parecida. Fiz com uma procedure que calcula os intervalos (quebra de sequência da tabela). Nesta procedure tive a ajuda de um grande amigo programador (Wendel Gualberto - Sankhya Uberlândia).

 

Mas mesmo assim, muito obrigado. Fica aí o script para a galera deliciar e se algum dia precisar.

 

Abraços.

 

Humberto Oliveira

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.