quinta-feira, 19 de maio de 2011

#11 - HAVING sem GROUP BY, pode???

Resolvi fazer esse post depois que tive a oportunidade de ler a prova do último concurso dos Correios realizado no dia14 de maio,  a banco que fez as provas foi CESPE/UNB, eles separam 3 questões especificas sobre bando de dados, segue a baixo a questão que me levantou a dúvida:



Ao ler a questão na minha mente já veio na minha mente que a resposta seria "ERRADA", mas ao olhar o gabarito qual foi a minha surpresa? Estava "CERTA". Conversando com algumas pessoas que são rato de concursos houve uma discussão entre MER e SQL.

Então fui pesquisar mais, e analisando cheguei a seguinte conclusão a questão não fala de MER, nem cita um banco específico então estamos trabalhando com o SQL padrão ANSI, no qual todos os SGDB estão padronizados.

O uso do GROUP BY, serve para agrupar os dados de uma pesquisa, vamos aos exemplos:

Use AdventureWorks
Go

select * from Sales.SalesOrderDetail
Go



Seria bem complicado sair somando as vendas por cada tipo de produto, então entra a cláusula GROUP BY:

select ProductID from Sales.SalesOrderDetail
group by ProductID

A cláusula GROUP BY pode trabalhar em conjunto com funções de agregação como por exemplo COUNT, SUM, MIN, MAX


select ProductID, COUNT(*) as QTD, SUM(UnitPrice) AS PRECO  from Sales.SalesOrderDetail

  group by ProductID

Agora vem o uso da cláusula "HAVING" só pode ser usada em conjunto como o GROUP BY, 

select ProductID, COUNT(*) as QTD, SUM(UnitPrice) AS PRECO  from Sales.SalesOrderDetail
  group by ProductID
   having SUM(UnitPrice) > 2000.00

 select ProductID, COUNT(*) as QTD, SUM(UnitPrice) AS PRECO  from Sales.SalesOrderDetail
  group by ProductID
   having ProductID = 925

select ProductID, COUNT(*) as QTD, SUM(UnitPrice) AS PRECO  from Sales.SalesOrderDetail
  group by ProductID
   having MIN(UnitPrice) = 8.99

Em forma simples de explicar, funciona como um WHERE dentro de uma consulta que está trazendo resultados agrupados, isso só funciona quando tem um GROUP BY. Não tem a possibilidade de executar uma consulta usando uma cláusula HAVING sem o GROUP BY. A condição HAVING precisa do GROUP BY para executar, como foi falado ele é uma condição de agregação que pode ser usado juntos outras funções de agregação.

A cláusula HAVING foi adicionado ao SQL porque a WHERE não pode ser usado com funções de agregação. O WHERE filtra de forma geral e não em uma agregação, o HAVING pode fazer where dentro de linhas que resultaram de uma agregação. 

Se você ainda ficar na dúvida tente rodar uma consulta dessas no seu banco sem o GROUP BY deixando somente o HAVING e veja se consegue.


2 comentários:

  1. Olá. Eu estava resolvendo a questão e fiquei na mesmo duvida. Marquei certo.

    Olhe aqui
    http://pgdocptbr.sourceforge.net/pg80/queries-table-expressions.html

    O PostgreSQL aceita sem o group by. A questao merecia ANULAÇÃO

    abraço.

    ResponderExcluir
  2. no gabarito definito o cespe considerou a questão errada.
    Voce esta certo!

    ResponderExcluir