Agrupamento e loops
Os comandos GROUP e LOOP oferecem duas formas de execução repetida de uma série de comandos. GROUP executa uma única iteração de um ou mais comandos em cada registro. LOOP executa várias iterações de uma série de comandos em um único registro e somente pode ser usada dentro de um bloco de GROUP.
Um exemplo simples de GROUP
Você tem uma tabela de dados de fatura denominada Trans_Cp. Usando esses dados, você precisa para calcular um total acumulado dos valores da fatura:
Número_Fornecedor | Nome_Fornecedor | Cidade_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Quantidade | Custo_Unidade |
---|---|---|---|---|---|---|---|
11663 | Indústrias Poderosas | Belo Horizonte | 5981807 | 2000-11-17 | 618,30 | 90 | 6,87 |
13808 | NOVATECH Atacadista | Campinas | 2275301 | 2000-11-17 | 6705,12 | 976 | 6,87 |
12433 | Koro International | Itajaí | 6585673 | 2000-11-17 | 7955,46 | 1158 | 6,87 |
Para calcular esse valor, use o comando GROUP. Dentro de cada interação de GROUP, você:
- Calcula o total acumulado até o registro atual.
- Extrai o número, o valor, a data e o total acumulado da fatura para uma tabela de resultados.
OPEN Trans_Cp COMMENT define o valor inicial do total acumulado como zero ASSIGN v_total_acumulado = 0,00 COMMENT itera cada registro da tabela para calcular e extrair o total acumulado GROUP ASSIGN v_total_acumulado = v_total_acumulado + Valor_Fatura EXTRACT Número_Fatura, Valor_Fatura, Data_Fatura, v_total_acumulado AS "Total acumulado" TO resultados1 END
Na execução do script, os comandos dentro do bloco de GROUP são processados para cada registro da tabela, do início ao fim da tabela, e o total acumulado é calculado e extraído. Se pudéssemos acompanhar a execução do GROUP, teríamos o seguinte:
Primeira iteração de GROUP: total acumulado = 0,00 + 618,30
O GROUP adiciona o valor da fatura do primeiro registro ao total acumulado inicial de 0,00 e extrai os campos para a tabela de resultados:
Número_Fornecedor | Nome_Fornecedor | Cidade_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Quantidade | Custo_Unidade |
---|---|---|---|---|---|---|---|
11663 | Indústrias Poderosas | Belo Horizonte | 5981807 | 2000-11-17 | 618,30 | 90 | 6,87 |
13808 | NOVATECH Atacadista | Campinas | 2275301 | 2000-11-17 | 6705,12 | 976 | 6,87 |
12433 | Koro International | Itajaí | 6585673 | 2000-11-17 | 7955,46 | 1158 | 6,87 |
Segunda iteração de GROUP: total acumulado = 618,30 + 6705,12
O bloco de GROUP adiciona o valor da fatura do segundo registro ao novo total acumulado de 618,30 e extrai os campos para a tabela de resultados:
Número_Fornecedor | Nome_Fornecedor | Cidade_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Quantidade | Custo_Unidade |
---|---|---|---|---|---|---|---|
11663 | Indústrias Poderosas | Belo Horizonte | 5981807 | 2000-11-17 | 618,30 | 90 | 6,87 |
13808 | NOVATECH Atacadista | Campinas | 2275301 | 2000-11-17 | 6705,12 | 976 | 6,87 |
12433 | Koro International | Itajaí | 6585673 | 2000-11-17 | 7955,46 | 1158 | 6,87 |
Terceira iteração de GROUP: total acumulado = 7323,42 + 7955,46
O bloco de GROUP adiciona o valor da fatura do terceiro registro ao novo total acumulado de 7323,42 e extrai os campos para a tabela de resultados:
Número_Fornecedor | Nome_Fornecedor | Cidade_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Quantidade | Custo_Unidade |
---|---|---|---|---|---|---|---|
11663 | Indústrias Poderosas | Belo Horizonte | 5981807 | 2000-11-17 | 618,30 | 90 | 6,87 |
13808 | NOVATECH Atacadista | Campinas | 2275301 | 2000-11-17 | 6705,12 | 976 | 6,87 |
12433 | Koro International | Itajaí | 6585673 | 2000-11-17 | 7955,46 | 1158 | 6,87 |
Tabela de resultados final
Após o processamento do registro final da tabela pelo GROUP, você terá a seguinte tabela de resultados:
Número_Fatura | Valor_Fatura | Data_Fatura | Total_acumulado |
---|---|---|---|
5981807 | 618,30 | 2000-11-17 | 618,30 |
2275301 | 6705,12 | 2000-11-17 | 7323,42 |
6585673 | 7955,46 | 2000-11-17 | 15278,88 |
Processamento de casos diferentes usando GROUP IF
Usando a mesma tabela Trans_Cp acima, agora você precisa calcular os totais acumulados para três tipos de faturas:
- Valor alto (maior ou igual a 1000,00)
- Valor médio (entre 100,00 e 1000,00)
- Valor baixo (menor que 100,00)
O COMANDO GROUP oferece uma estrutura IF/ELSE para processar casos diferentes. Você informa as expressões condicionais a serem testadas. Se um registro for avaliado como verdadeiro, os comandos dentro do bloco serão executados.
Como os casos são testados
Os casos são testados de cima para baixo e um registro pode ser processado por apenas um bloco IF/ELSE. O primeiro caso que for avaliado como verdadeiro para o registro processará esse registro:
- Quando o GROUP processa o primeiro registro, testa a primeira condição IF (Valor_Fatura >= 1000). Se a condição for avaliada como verdadeira, o código desse caso será executado e nenhum outro caso será testado.
- Se o primeiro caso for avaliado como falso, a próxima condição ELSE IF (Valor_Fatura >= 100) será testada. Da mesma forma, se esse teste for avaliado como verdadeiro, o código desse caso será executado e nenhum outro caso será testado.
- Finalmente, se nenhum dos casos IF ou ELSE IF for avaliado como verdadeiro, o caso padrão no bloco ELSE processará o registro.
Nota
Se um registro for avaliado como verdadeiro em mais de um caso, será processado apenas pelo primeiro bloco IF/ELSE testado. Os registros nunca são processados por mais de um bloco IF/ELSE em um comando GROUP.
OPEN Trans_Cp COMMENT define valores iniciais para os totais acumulados ASSIGN v_total_acumulado_alto = 0,00 ASSIGN v_total_acumulado_medio = 0,00 ASSIGN v_total_acumulado_baixo = 0,00 COMMENT usa GROUP IF para executar comandos ASSIGN e EXTRACT diferentes, dependendo do valor da fatura GROUP IF Valor_Fatura >= 1000 ASSIGN v_total_acumulado_alto = v_total_acumulado_alto + Valor_Fatura EXTRACT Número_Fatura, Valor_Fatura, Data_Fatura, v_total_acumulado_alto AS "Total acumulado" TO resultados_alto GROUP IF Valor_Fatura >= 100 ASSIGN v_total_acumulado_medio = v_total_acumulado_medio + Valor_Fatura EXTRACT Número_Fatura, Valor_Fatura, Data_Fatura, v_total_acumulado_medio AS "Total acumulado" TO resultados_medio ELSE ASSIGN v_total_acumulado = v_total_acumulado_baixo + Valor_Fatura EXTRACT Número_Fatura, Valor_Fatura, Data_Fatura, v_total_acumulado_baixo AS "Total acumulado" TO resultados_baixo END
Quando o script é executado, o comando GROUP testa o valor da fatura de cada registro. Dependendo do valor, o registro será usado para atualizar um dos três totais acumulados (alto, médio, baixo), gerando três tabelas de resultados.
LOOP dentro de um GROUP
Ao usar GROUP para processar registros de uma tabela, você pode usar um comando LOOP para executar diversos comandos várias vezes em um único registro. O LOOP é uma segunda iteração dentro da iteração de GROUP e é executado até que uma condição de teste especificada seja avaliada como falsa.
Usando LOOP para dividir um campo
Você tem a seguinte tabela com dados de fatura e precisa isolar informações específicas para valores de fatura por departamento. Uma fatura pode ser relacionada a mais de um departamento, e os códigos de departamento são armazenados em formato delimitado por vírgulas na tabela:
Número_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Código_Departamento |
---|---|---|---|---|
11663 | 5981807 | 2000-11-17 | 618,30 | CCD,RDR |
13808 | 2275301 | 2000-11-17 | 6705,12 | CCD |
12433 | 6585673 | 2000-11-17 | 7955,46 | CCD,LMO,RDR |
Para extrair os valores de fatura por departamento, você:
- Usa um comando GROUP para processar a tabela registro a registro.
- Calcula o número de departamentos (n) associados a cada registro.
- Usa o comando LOOP para iterar o registro n vezes para extrair dados de cada departamento associado ao registro.
Nota
Você precisa incrementar a variável v_contador dentro de LOOP. Caso contrário, o teste WHILE será sempre avaliado como verdadeiro e o script entrará em um loop infinito. É possível incluir um comando SET LOOP nos scripts para evitar loops infinitos. Para obter mais informações, consulte Comando SET.
COMMENT Usa GROUP para contar vírgulas em cada campo de código de departamento como forma de identificar quantos departamentos estão associados ao registro Executa LOOP em cada registro para cada código do campo, extraindo cada código em seu próprio registro END GROUP v_quantidade_departamentos = OCCURS(Código_Departamento;',') v_contador = 0 LOOP WHILE v_contador <= v_quantidade_departamentos v_depto = SPLIT(Código_Departamento; ','; (v_contador + 1)) EXTRACT FIELDS Número_Fatura, Valor_Fatura, v_depto AS "Departamento" TO resultado1 v_contador = v_contador + 1 END END
Na execução do script, os comandos dentro do bloco de GROUP são processados para cada registro da tabela, do início ao fim da tabela. Para cada registro, o comando LOOP itera o registro uma vez por código departamento na lista delimitada por vírgulas e extrai um registro. Se pudéssemos acompanhar a execução do GROUP e do Loop, teríamos o seguinte:
Primeira iteração de GROUP: 2 iterações de LOOP
Número_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Código_Departamento |
---|---|---|---|---|
11663 | 5981807 | 2000-11-17 | 618,30 | CCD,RDR |
13808 | 2275301 | 2000-11-17 | 6705,12 | CCD |
12433 | 6585673 | 2000-11-17 | 7955,46 | CCD,LMO,RDR |
Para o primeiro registro na tabela, o valor de v_quantidade_departamentos é 1. Portanto, LOOP itera duas vezes:
- Para a primeira iteração do LOOP:
- v_contador = 0
- v_depart = CCD
O registro a seguir é extraído e o valor de v_contador é incrementado para 1. Portanto, LOOP itera novamente:
5981807 618,30 CCD - Para a segunda interação do LOOP:
- v_contador = 1
- v_depart = RDR
O registro a seguir é extraído e o valor de v_contador é incrementado para 2. Portanto, LOOP itera novamente e GROUP prossegue para o próximo registro:
5981807 618,30 RDR
Segunda iteração de GROUP: 1 iterações de LOOP
Número_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Código_Departamento |
---|---|---|---|---|
11663 | 5981807 | 2000-11-17 | 618,30 | CCD,RDR |
13808 | 2275301 | 2000-11-17 | 6705,12 | CCD |
12433 | 6585673 | 2000-11-17 | 7955,46 | CCD,LMO,RDR |
Para o segundo registro na tabela, o valor de v_quantidade_departamentos é 0. Portanto, LOOP itera uma vez:
- v_contador = 0
- v_depart = CCD
O registro a seguir é extraído e o valor de v_contador é incrementado para 1. Portanto, LOOP itera novamente e GROUP prossegue para o próximo registro:
2275301 | 6705,12 | CCD |
Terceira iteração de GROUP: 3 iterações de LOOP
Número_Fornecedor | Número_Fatura | Data_Fatura | Valor_Fatura | Código_Departamento |
---|---|---|---|---|
11663 | 5981807 | 2000-11-17 | 618,30 | CCD,RDR |
13808 | 2275301 | 2000-11-17 | 6705,12 | CCD |
12433 | 6585673 | 2000-11-17 | 7955,46 | CCD,LMO,RDR |
Para o terceiro registro na tabela, o valor de v_quantidade_departamentos é 2. Portanto, LOOP itera três vezes:
- Para a primeira iteração do LOOP:
- v_contador = 0
- v_depart = CCD
O registro a seguir é extraído e o valor de v_contador é incrementado para 1. Portanto, LOOP itera novamente:
6585673 7955,46 CCD - Para a segunda interação do LOOP:
- v_contador = 1
- v_depart = LMO
O registro a seguir é extraído e o valor de v_contador é incrementado para 2. Portanto, LOOP itera novamente:
6585673 7955,46 LMO - Para a terceira iteração do LOOP:
- v_contador = 2
- v_depart = RDR
O registro a seguir é extraído e o valor de v_contador é incrementado para 3. Portanto, LOOP itera novamente e GROUP prossegue para o próximo registro:
6585673 7955,46 CCD
Tabela de resultados final
Depois que GROUP processou cada registro da tabela e LOOP iterou por todos os códigos de departamento, você terá a seguinte tabela de resultados:
Número_Fatura | Valor_Fatura | Departamento |
---|---|---|
5981807 | 618,30 | CCD |
5981807 | 618,30 | RDR |
2275301 | 6705,12 | CCD |
6585673 | 7955,46 | CCD |
6585673 | 7955,46 | LMO |
6585673 | 7955,46 | RDR |