Penggunaan HAVING tanpa GROUP BY dalam kueri SQL

26

Untuk menggunakan HAVINGdalam query SQL, haruskah ada GROUP BYagregat nama kolom?

Apakah ada kasus khusus di mana dimungkinkan untuk digunakan HAVINGtanpa GROUP BYdalam query SQL?

Haruskah mereka hidup berdampingan pada saat yang sama?

Kutu buku komputer
sumber

Jawaban:

25

Tidak.

Mereka tidak harus hidup berdampingan, sebagaimana dibuktikan oleh fakta bahwa permintaan berikut dalam Oracle berfungsi:

select * from dual having 1 = 1;

Demikian pula, di PostgreSQL kueri berikut berfungsi:

select 1 having 1 = 1;

Jadi having tidak perlu group by .

Setelah diterapkan setelah fase agregasi dan harus digunakan jika Anda ingin memfilter hasil agregat. Jadi kebalikannya tidak benar, dan yang berikut ini tidak akan berfungsi:

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

Anda harus mengganti wheredengan havingdalam hal ini, sebagai berikut:

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

NB Formulir permintaan berikut juga akan berfungsi:

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

Anda dapat melihat bahwa menggunakan havinghanyalah versi singkat dari kueri terakhir ini.


Singkatnya, havingditerapkan setelah para group byfase sedangkan wherediterapkan sebelum itu group byfase.

Colin 't Hart
sumber
2
Contoh lain:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ
1
Iya nih. Dan PostgreSQL memungkinkan konstruk berikut select 1 having count(*) = 1;yang belum saya pahami.
Colin 't Hart
SQL Server memungkinkan juga, SELECT 1 AS id, 'Colin' AS name;sementara yang lain seperti Oracle memiliki dualtabel khusus . Saya tidak berpikir bahwa salah satu dari sintaks ini adalah ANSI / ISO SQL (yang mengharuskan FROM).
ypercubeᵀᴹ
Saya tidak bermaksud kurangnya fromtetapi referensi count(*)dalam havingklausa tanpa indikasi untuk mana kolom ini sedang dikumpulkan. Agaknya agregat di atas semua kolom dalam selectklausa.
Colin 't Hart
Ah baiklah. Ya, saya setuju bahwa itulah yang dilakukannya (agregat untuk semua baris yang Anda maksud - di atas semua baris tabel kosong).
ypercubeᵀᴹ
4

Memiliki digunakan untuk menyaring grup.

di mana klausa digunakan untuk menyaring baris.

sqlengineer
sumber
1
Pernyataan pertama Anda tidak benar. havingadalah diterapkan setelah fase agregasi sehingga dapat digunakan untuk kelompok filter.
Colin 't Hart
1

HAVING sedang memfilter grup. Jika Anda belum mengelompokkan berdasarkan sebab, semua baris menyajikan satu grup. Jadi, jika predikat di HAVING dinilai benar, Anda mendapatkan satu baris, jika tidak, tidak ada baris.

msi77
sumber
1

Dengan tidak adanya klausa GROUP BY, kueri menganggap seluruh hubungan sebagai satu kelompok.

misalnya

     select count(*)
     from dual
     having count(*) > 5;
Vikrant Singh
sumber