Uso de HAVING sem GROUP BY em consultas SQL


26

Para usar HAVINGem consultas SQL, deve haver um GROUP BYpara agregar os nomes das colunas?

Existem casos especiais em que é possível usar HAVINGsem GROUP BYconsultas SQL?

Eles devem coexistir ao mesmo tempo?

Respostas:


25

Não.

Eles não precisam coexistir, conforme comprovado pelo fato de que a seguinte consulta no Oracle funciona:

select * from dual having 1 = 1;

Da mesma forma, no PostgreSQL, a seguinte consulta funciona:

select 1 having 1 = 1;

Então having não requer group by .

Ter é aplicado após a fase de agregação e deve ser usado se você deseja filtrar os resultados agregados. Portanto, o inverso não é verdadeiro e o seguinte não funciona:

select a, count(*) as c
from mytable
group by a
where c > 1;

Você precisa substituir wherepor havingneste caso, da seguinte maneira:

select a, count(*) as c
from mytable
group by a
having c > 1;

NB O seguinte formulário de consulta também funcionará:

select *
from (
  select a, count(*) as c
  from mytable
  group by a
)
where c > 1;

Você pode ver que usar havingé simplesmente uma versão abreviada desta última consulta.


Em resumo, havingé aplicado após a group byfase, enquanto whereé aplicado antes da group byfase.


2
Outro exemplo:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ

11
Sim. E o PostgreSQL permite a seguinte construção select 1 having count(*) = 1;que ainda não compreendi.
Colin 't Hart

O SQL Server também permite, SELECT 1 AS id, 'Colin' AS name;enquanto outros, como o Oracle, têm uma dualtabela especial . Eu não acho que nenhuma dessas sintaxes seja ANSI / ISO SQL (que requer FROM).
precisa saber é o seguinte

Eu não quis dizer a falta de, frommas a referência count(*)na havingcláusula sem qualquer indicação sobre quais colunas estão sendo agregadas. Presumivelmente, ele agrega todas as colunas da selectcláusula.
Colin 'Hart

Ah ok. Sim, eu concordo que é isso que faz (agregado em todas as linhas que você quer dizer - em todas as linhas de uma tabela vazia).
precisa saber é o seguinte


1

TENDO está filtrando os grupos. Se você não tiver uma causa GROUP BY, todas as linhas apresentarão um grupo. Portanto, se o predicado em HAVING for avaliado como verdadeiro, você obterá uma linha, caso contrário, nenhuma linha.


1

Na ausência da cláusula GROUP BY, a consulta considera toda a relação como um grupo.

por exemplo

     select count(*)
     from dual
     having count(*) > 5;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.