Agrupamento de linhas 3x3 em um select.

Scripts Diversos para o Oracle SQL*Plus. (Relacionado a ferramenta Oracle SQL*Plus, para questões de SQL, usar o forum SQL)
Responder
jdfuhr
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 27 Jul 2010 2:59 pm
Localização: Florianópolis - SC

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

Selecionar tudo

NF 1
NF 2
NF 3
.
.
.
NF N
NF 1

Selecionar tudo

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

Selecionar tudo

1 X BOLACHA ISABELA 
NF 3

Selecionar tudo

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

Selecionar tudo

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

Selecionar tudo

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.
Diego_Mello
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 229
Registrado em: Sex, 05 Set 2008 2:59 pm
Localização: Igrejinha - RS
Diego Mello
Igrejinha - RS
www.twitter.com/diegolmello

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

Selecionar tudo

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
 
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

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

Selecionar tudo

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
 
:-o
jdfuhr
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 27 Jul 2010 2:59 pm
Localização: Florianópolis - SC

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 Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 27 Jul 2010 2:59 pm
Localização: Florianópolis - SC

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
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

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:

Selecionar tudo

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):

Selecionar tudo

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:

Selecionar tudo

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

Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 9 visitantes