Pular para o conteúdo principal

O que devemos conhecer sobre SQL/Oracle Parte 13: Gerando resultados com o agrupamento de dados relacionados


Utilizando a operação ROLLUP para produzir valores subtotais



O ROLLUP é uma subcláusula do GROUP BY, ele realiza agrupamento de dados agrupados, esses registros são conhecidos como superagregados. É normalmente utilizado com SUM, mas nada impede que ele seja utilizado com outras funções de agrupamento. Seu resultado é um registro de sumarização simples para cada agrupamento:



select d.descricao departamento, c.descricao cargo, sum(salario) total
from funcionarios  f
join cargos        c
on c.codigo      = f.cod_cargo
join departamentos d
on d.codigo      = c.cod_dep
group by rollup (d.descricao, c.descricao)
order by d.descricao, c.descricao

No comando acima, além de termos as somas dos salários por cargo, também teremos um total por departamento.

Resumindo:

  • ROLLUP apenas é permitido com a cláusula GROUP BY;
  • ROLLUP calcula subtotais e totais para os grupos de registros;
  • ROLLUP vem após o GROUP BY;
  • Após o ROLLUP vêm os itens do GROUP BY que devem ser agregados;
  • ROLLUP pode possuir mais de uma expressão, separadas por vírgula;


Utilizando a operação CUBE para produzir valores CROSSTABULATIONS


O CUBE assim como o ROLLUP é uma subcláusula do GROUP BY, porém ele é capaz de gerar uma totalização para cada agrupamento encontrado:

select d.descricao departamento, c.descricao cargo, sum(salario) total
from funcionarios  f
join cargos        c
on c.codigo      = f.cod_cargo
join departamentos d
on d.codigo      = c.cod_dep
group by cube (d.descricao, c.descricao)
order by d.descricao, c.descricao

No exemplo acima além de termos as somas dos salários por cargo e o total por departamento, teremos também o total que cada cargo possui.

Resumindo:
  • CUBE só é permitido com GROUP BY;
  • CUBE produz totais e subtotais para todas as combinações possíveis de um agrupamento;
  • CUBE vem após o GROUP BY seguido das expressões entre parênteses;


Utilizando a função GROUPING para identificar registros ROLLUP e CUBE


A função GROUPING retorna um numero, zero ou um, indicando se o registro é agregado (zero), ou superagregado (um):

select grouping(d.descricao), d.descricao departamento, c.descricao cargo, sum(salario) total
from funcionarios  f
join cargos        c
on c.codigo      = f.cod_cargo
join departamentos d
on d.codigo      = c.cod_dep
group by rollup (d.descricao, c.descricao)
order by d.descricao, c.descricao

Resumindo:
  • A função GROUPING identifica registros agrupados, sejam regulares ou superagregados;
  • Registros regulares não são ROLLUP ou CUBE;
  • Superagregados são resultados gerados por ROLLUP ou CUBE;
  • O GROUPING retorna 0 para registros regulares e 1 para superagregados;
  • É possível combinar o GROUPING com outras funções;


Utilizando GROUPING SETS para produzir resultados simplificados


O GROUPING SETS também é uma subcláusula do GROUP BY, ele permite refinar o resultado dos agrupamentos, sendo possível especificar quais grupos desejamos mostrar:

select d.descricao departamento, c.descricao cargo, decode(f.sexo, 'M', 'HOMENS', 'F', 'MULHERES') grupo, sum(salario) total
  from funcionarios  f
  join cargos        c
    on c.codigo      = f.cod_cargo
  join departamentos d
    on d.codigo      = c.cod_dep
 group by grouping sets ((d.descricao, c.descricao), (f.sexo), null)
  order by d.descricao, c.descricao, f.sexo

No exemplo acima definimos que nosso primeiro agrupamento será a combinação ((d.descricao, c.descricao), depois (f.sexo) e por fim o null que indica o total, como resultado teremos um registro para cada combinação definida, incluindo o total.

Resumindo:
  • GROUPING SETS são geralmente utilizados para consultas que geram múltiplos grupos;
  • GROUPING SETS permitem a definição dos grupos a serem recuperados, apenas para os resultados desejados;


Comentários

Mais visitadas

Alterar cores do PageControl (Delphi)

O padrão Windows todo cinza não é muito atraente, por isso quando nos utilizarmos do PageControl podemos alterar suas cores e fontes da seguinte maneira: Em primeiro lugar devemos alterar a propriedade OwnerDraw para TRUE ; Depois implementar seu método DrawTab da seguinte maneira: //pinta a fonte Control.Canvas.Font.Color:=clBlack; // // pinta a paleta / aba Control.Canvas.brush.Color:=clSkyBlue; PageControl1.Canvas.Rectangle(Rect); Control.Canvas.TextOut(Rect.left+5,Rect.top+3,PageControl1.Pages[tabindex].Caption); // pinta a parte interna (tabsheet) PageControl1.Pages[TabIndex].brush.Color := Control.Canvas.brush.Color; PageControl1.Pages[TabIndex].Repaint; Caso a intenção seja manter cada aba com seu próprio estilo basta adicionar um CASE filtrando o índice das abas: case TabIndex of   0: Control.Canvas.Font.Color:=clBlack;   1: Control.Canvas.Font.Color:=clWindow; ...

Funções de Data e Hora (Delphi)

É muito comum nos depararmos no dia a dia com a necessidade de manipular datas e horas, seja para um calculo de permanência, dias de atraso enfim, é praticamente escapar de alguma situação que necessite desse tipo de controle. Assim como a necessidade e se utilizar algum recurso para manipular as datas e horas de alguma maneira e freqüente, as duvidas de como o faze-lo também é, basta um breve olhar em qualquer fórum especializado e lá está, alguma duvida relacionada, por isso decidi falar um pouco sobre uma unit muito poderosa chamada DateUtils para a manipulação de data e hora, com um grande numero de métodos e classes que facilitam a vida de qualquer um. Alguns exemplos: CompareDate(constA, B: TDateTime): TValueRelationship; Compara apenas a data de dois valores (do tipo TDateTime) retornando: LessThanValue O primeiro valor é menor que o segundo EqualsValue Os valores são iguais GreaterThanValue O primeiro valor é maior que o segundo CompareDateTime(const A, B: TD...

Como pegar valor de coluna invisível do GridView

Em determinado momento nos deparamos com a seguinte situação, nossa tabela do banco de dados possui como campo chave, um ID por exemplo, incrementado por uma rotina da aplicação, do banco ou algum outro mecanismo de incremento (sequences, increment, etc), logo não há porque mostrar essa coluna para o usuário porque o mesmo não sabe de sua existência, e seu valor não tem qualquer relevância para ele, sendo assim o mais lógico a se fazer é não mostra-lá na aplicação. Seu valor é necessário já que por se tratar de uma chave primária precisaremos dela para atualizar, inserir ou excluir os dados, então o que fazer? A resposta seria simples, deixemos ele invisível, buscaremos seu valor e o usuário não perceberá, porém a partir da versão 2005 do visual Studio as colunas setadas com "visible = false" não são renderizadas, com isso ao se tentar acessar seu valor o que recebemos é nada. Para contornarmos essa situação podemos codificar o seguinte: protected void GridView1_R...