FAQ Procura Membros Registre-se Perfil MP's Login/Out
Agrupamento de linhas 3x3 em um select.

 
Novo Tópico   Responder Mensagem    glufke.net - Índice do Fórum -> SQL*Plus
Mensagem Autor
Enviada: Qua, 28 Jul 2010 4:20 pm     Assunto: Agrupamento de linhas 3x3 em um select.

Boa tarde,

estou desenvolvendo um select para me apresentar os produtos das notas de uma determinada Ordem de Carga. Até então tudo bem, minha dificuldade está na necessidade de agrupar os produtos dessas notas agrupados de 3 em 3 notas, ou seja:

Ordem de Carga 3
NF 1
NF 2
NF 3
.
.
.
NF N

NF 1
3 X BOLACHA ISABELA
2 X LEITE CONDENÇADO
5 X PIPOCA YOKI

NF2
1 X BOLACHA ISABELA

NF 3
3 X BOLACHA ISABELA
5 X PIPOCA YOKI
2 X BOLACHA RECHEADA TORTINHAS

NF 4
1 X BOLACHA ISABELA
1 X PIPOCA YOKI
1 X BOLACHA RECHEADA TORTINHAS

ASSIM POR DIANTE.

O Resultado desejado no meu select seria este:

Separação da ordem de carga 3
7 X BOLACHA ISABELA
2 X LEITE CONDENÇADO
10 X PIPOCA YOKI
----------------------------------------------------------------------------
1 X BOLACHA ISABELA
1 X PIPOCA YOKI
1 X BOLACHA RECHEADA TORTINHAS

para um melhor entendimento:
No primeiro bloco de produtos apresentado seriam agrupados os produtos das notas 1, 2 e 3. No segundo bloco as notas 4, 5 e 6 e assim por diante.

Alguém conhece alguma função onde eu poderia realizar este agrupamento?

desde já agradeço a atenção.
jdfuhr
Rank: Estagiário Pleno
Rank: Estagiário Pleno


Registrado em: Ter, 27 de Julho de 2010
Mensagens: 3
Cidade - UF: Florianópolis - SC


Enviada: Qua, 28 Jul 2010 5:06 pm    

Tu pode fazer algo assim, mas com SQL é meio limitado.
Tu não pode fazer um relatório?

Código:

SQL> SELECT a
  2        ,b
  3    FROM (WITH tt AS (SELECT 1 a, 2 b
  4                        FROM dual UNION
  5                      SELECT 2 a, 3 b
  6                        FROM dual UNION
  7                      SELECT 3 a, 4 b
  8                        FROM dual UNION
  9                      SELECT 4 a, 5 b
 10                        FROM dual UNION
 11                      SELECT 5 a, 6 b
 12                        FROM dual UNION
 13                      SELECT 6 a, 7 b
 14                        FROM dual UNION
 15                      SELECT 7 a, 8 b
 16                        FROM dual UNION
 17                      SELECT 8 a, 9 b
 18                        FROM dual)
 19           SELECT TO_CHAR(tt.a) a
 20                 ,TO_CHAR(tt.b) b
 21                 ,ROWNUM ordem_a
 22                 ,1 ordem_b
 23                 ,1
 24             FROM tt
 25           UNION
 26           SELECT *
 27             FROM (SELECT a
 28                         ,b
 29                         ,oa + LEVEL - 1 oa
 30                         ,ob
 31                         ,max_tt
 32                     FROM (SELECT '-------------------------------------------' a
 33                                 ,'-------------------------------------------' b
 34                                 ,3 oa
 35                                 ,2 ob
 36                                 ,COUNT(*) max_tt
 37                             FROM dual
 38                                 ,tt)
 39                   CONNECT BY oa + LEVEL - 1 <= max_tt)
 40            WHERE MOD(oa, 3) = 0)
 41            ORDER BY ordem_a
 42                    ,ordem_b
 43  ;
 
A                                           B
------------------------------------------- -------------------------------------------
1                                           2
2                                           3
3                                           4
------------------------------------------- -------------------------------------------
4                                           5
5                                           6
6                                           7
------------------------------------------- -------------------------------------------
7                                           8
8                                           9
 
10 rows selected
 

_________________
Diego Mello
Igrejinha - RS
www.twitter.com/diegolmello
Diego_Mello
Rank: DBA Júnior
Rank: DBA Júnior


Registrado em: Sex, 5 de Setembro de 2008
Mensagens: 185
Cidade - UF: Igrejinha - RS


Enviada: Qua, 28 Jul 2010 5:07 pm    

Diego_Mello escreveu:
Tu pode fazer algo assim, mas com SQL é meio limitado.
Tu não pode fazer um relatório?

Código:

SQL> SELECT a
  2        ,b
  3    FROM (WITH tt AS (SELECT 1 a, 2 b
  4                        FROM dual UNION
  5                      SELECT 2 a, 3 b
  6                        FROM dual UNION
  7                      SELECT 3 a, 4 b
  8                        FROM dual UNION
  9                      SELECT 4 a, 5 b
 10                        FROM dual UNION
 11                      SELECT 5 a, 6 b
 12                        FROM dual UNION
 13                      SELECT 6 a, 7 b
 14                        FROM dual UNION
 15                      SELECT 7 a, 8 b
 16                        FROM dual UNION
 17                      SELECT 8 a, 9 b
 18                        FROM dual)
 19           SELECT TO_CHAR(tt.a) a
 20                 ,TO_CHAR(tt.b) b
 21                 ,ROWNUM ordem_a
 22                 ,1 ordem_b
 23                 ,1
 24             FROM tt
 25           UNION
 26           SELECT *
 27             FROM (SELECT a
 28                         ,b
 29                         ,oa + LEVEL - 1 oa
 30                         ,ob
 31                         ,max_tt
 32                     FROM (SELECT '-------------------------------------------' a
 33                                 ,'-------------------------------------------' b
 34                                 ,3 oa
 35                                 ,2 ob
 36                                 ,COUNT(*) max_tt
 37                             FROM dual
 38                                 ,tt)
 39                   CONNECT BY oa + LEVEL - 1 <= max_tt)
 40            WHERE MOD(oa, 3) = 0)
 41            ORDER BY ordem_a
 42                    ,ordem_b
 43  ;
 
A                                           B
------------------------------------------- -------------------------------------------
1                                           2
2                                           3
3                                           4
------------------------------------------- -------------------------------------------
4                                           5
5                                           6
6                                           7
------------------------------------------- -------------------------------------------
7                                           8
8                                           9
 
10 rows selected
 


Surprised
_________________
Jesus está voltando, volte antes para Ele.

Victor Hugo M. M.
victorhugomuniz
Moderador
Moderador


Registrado em: Sex, 1 de Fevereiro de 2008
Mensagens: 955
Cidade - UF: Rio de Janeiro - RJ


Enviada: Qua, 28 Jul 2010 5:11 pm    

Obrigado Victor,

estou tentando entender o funcionamento e testando.

Assim que tiver uma posição te passo.

Executando teu código aqui parece que vai funcionar.

Obrigado
jdfuhr
Rank: Estagiário Pleno
Rank: Estagiário Pleno


Registrado em: Ter, 27 de Julho de 2010
Mensagens: 3
Cidade - UF: Florianópolis - SC


Enviada: Qua, 28 Jul 2010 5:13 pm    

Obrigado Diego, (desculpe ter errado o nome antes)

estou tentando entender o funcionamento e testando.

Assim que tiver uma posição te passo.

Executando teu código aqui parece que vai funcionar.

Obrigado
jdfuhr
Rank: Estagiário Pleno
Rank: Estagiário Pleno


Registrado em: Ter, 27 de Julho de 2010
Mensagens: 3
Cidade - UF: Florianópolis - SC


Enviada: Qua, 28 Jul 2010 10:15 pm    

Lendo a pergunta, imaginei que a dúvida seja em como realizar o agrupamento dos itens de 3 em 3 notas, que é um probleminha interessante de resolver:

Código:

create table nota
( nf number
);
/
create table item
( nf number
, produto varchar2(10)
, quantidade number
);
/

insert into nota select 10*level from dual connect by level <= 10;

insert into item  select 10*(mod(level,10)+1),  'produto '||trunc(dbms_random.value(1,4)), trunc(dbms_random.value(1,8)  ) from dual connect by level <= 35;



O passo principal é realizar o agrupamento dos dados.
É possível realizar isso ordenando os resultados, e em seguida subtrair do número da linha o resto da divisão do número da linha anterior pelo tamanho de sua partição (3 no caso):
Código:

select n.*
     , rn -  mod( rn-1, 3 ) grupo
from
(
  select n.*
       -- basta mudar o order by para informar o critério de ordenação das 3 notas
       -- (data de emissão, filial, etc)
       , row_number()
         over(  order by n.nf
             ) rn
  from   nota n
) n
;


NF   RN   GRUPO
10   1    1
20   2    1
30   3    1
40   4    4
50   5    4
60   6    4
70   7    7
80   8    7
90   9    7
100 10    10


Com os dados já agrupados, basta realizar o join com a tabela de itens, e realizar o group by pela coluna grupo:

Código:

select grupo, produto, sum(quantidade) quantidade
from
(
  select n.*
       , rn -  mod( rn-1, 3 ) grupo
  from
  (
    select n.*
         -- basta mudar o order by para informar o critério de ordenação das 3 notas
         -- (data de emissão, filial, etc)
         , row_number()
           over(  order by n.nf
               ) rn
    from   nota n
  ) n
) n
, item i
where n.nf = i.nf
group by grupo, produto
order by grupo, produto
;

GRUPO       PRODUTO     QUANTIDADE
1           produto 1           15
1           produto 2           17
1           produto 3           19
4           produto 1           33
4           produto 2           17
4           produto 3           13
7           produto 1           18
7           produto 2           3
7           produto 3           14
10          produto 1           5
10          produto 2           6
10          produto 3           3


_________________
Rafael O. Genaro
rogenaro
Rank: DBA Júnior
Rank: DBA Júnior


Registrado em: Sex, 30 de Março de 2007
Mensagens: 186
Cidade - UF: Londrina - PR


Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    glufke.net - Índice do Fórum -> SQL*Plus Todos os horários são GMT - 3 Hours
Página 1 de 1

 
 
. .