Sử dụng HAVING mà không có NHÓM THEO trong các truy vấn SQL


26

Để sử dụng HAVINGtrong các truy vấn SQL, phải có một GROUP BYtổng hợp các tên cột?

Có trường hợp đặc biệt nào có thể sử dụng HAVINGmà không cần GROUP BYtruy vấn SQL không?

Họ phải cùng tồn tại cùng một lúc?

Câu trả lời:


25

Không.

Họ không phải cùng tồn tại, như đã được chứng minh bằng thực tế là truy vấn sau trong Oracle hoạt động:

select * from dual having 1 = 1;

Tương tự, trong PostgreSQL, truy vấn sau đây hoạt động:

select 1 having 1 = 1;

Vì vậy, having không yêu cầu group by .

Có được áp dụng sau giai đoạn tổng hợp và phải được sử dụng nếu bạn muốn lọc kết quả tổng hợp. Vì vậy, điều ngược lại là không đúng và những điều sau đây sẽ không hoạt động:

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

Bạn cần thay thế wherebằng havingtrong trường hợp này, như sau:

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

NB Mẫu truy vấn sau đây cũng sẽ hoạt động:

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

Bạn có thể thấy rằng việc sử dụng havingchỉ đơn giản là một phiên bản tốc ký của truy vấn cuối cùng này.


Nói tóm lại, havingđược áp dụng sau khi các group bygiai đoạn trong khi wheređược áp dụng trước các group bygiai đoạn.


2
Một ví dụ khác:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ

1
Vâng. Và PostgreSQL cho phép cấu trúc sau select 1 having count(*) = 1;mà tôi chưa nắm bắt được.
Colin 't Hart

SQL Server cũng cho phép, SELECT 1 AS id, 'Colin' AS name;trong khi những người khác như Oracle có một dualbảng đặc biệt . Tôi không nghĩ rằng một trong hai cú pháp này là ANSI / ISO SQL (yêu cầu FROM).
ypercubeᵀᴹ

Tôi không có nghĩa là thiếu fromnhưng tham chiếu đến count(*)trong havingmệnh đề mà không có bất kỳ dấu hiệu nào về việc cột này sẽ được tổng hợp. Có lẽ nó tổng hợp trên tất cả các cột trong selectmệnh đề.
Colin 't Hart

À được rồi Vâng, tôi đồng ý rằng đó là những gì nó làm (tổng hợp trên tất cả các hàng bạn muốn nói - trên tất cả các hàng của một bảng trống).
ypercubeᵀᴹ


1

HAVING đang lọc các nhóm. Nếu bạn chưa có NHÓM theo nguyên nhân, tất cả các hàng sẽ trình bày một nhóm. Vì vậy, nếu vị ngữ trong HAVING đánh giá là đúng, bạn sẽ nhận được một hàng, nếu không thì không có hàng nào.


1

Trong trường hợp không có mệnh đề GROUP BY, truy vấn coi toàn bộ quan hệ là một nhóm.

ví dụ

     select count(*)
     from dual
     having count(*) > 5;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.