การใช้ HAVING ที่ไม่มี GROUP BY ในการสืบค้น SQL


26

เพื่อที่จะใช้HAVINGในการสืบค้น SQL จะต้องมีการGROUP BYรวมชื่อคอลัมน์หรือไม่

มีกรณีพิเศษที่สามารถใช้งานได้HAVINGโดยไม่ต้องมีGROUP BYแบบสอบถาม SQL หรือไม่?

พวกเขาจะต้องอยู่ร่วมกันในเวลาเดียวกันหรือไม่?

คำตอบ:


25

เลขที่

พวกเขาไม่จำเป็นต้องอยู่ร่วมกันดังที่พิสูจน์แล้วโดยความจริงที่ว่าแบบสอบถามต่อไปนี้ใน Oracle ทำงานได้:

select * from dual having 1 = 1;

ในทำนองเดียวกันใน PostgreSQL เคียวรีต่อไปนี้จะทำงาน:

select 1 having 1 = 1;

ดังนั้นhaving ไม่ จำเป็นต้องมี group by

มีการนำมาใช้ หลังจากขั้นตอนการรวมและจะต้องใช้ถ้าคุณต้องการกรองผลลัพธ์รวม ดังนั้นการย้อนกลับไม่เป็นความจริงและสิ่งต่อไปนี้จะไม่ทำงาน:

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

คุณต้องแทนที่whereด้วยhavingในกรณีนี้ดังนี้:

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

NB แบบฟอร์มแบบสอบถามต่อไปนี้จะใช้งานได้:

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

คุณจะเห็นว่าการใช้havingเป็นเพียงแค่ชวเลขรุ่นสุดท้ายของแบบสอบถามนี้


สรุปแล้วhavingถูกนำไปใช้หลังจากgroup byขั้นตอนในขณะที่whereถูกนำไปใช้ก่อนgroup byเฟส


2
อีกตัวอย่างหนึ่ง:SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);
ypercubeᵀᴹ

1
ใช่. และ PostgreSQL อนุญาตให้สร้างสิ่งต่อไปนี้select 1 having count(*) = 1;ซึ่งฉันยังไม่เข้าใจ
โคลิน 't ฮาร์ต

SQL Server ก็เช่นกันSELECT 1 AS id, 'Colin' AS name;ในขณะที่คนอื่น ๆ เช่น Oracle มีdualตารางพิเศษ ฉันไม่คิดว่าไวยากรณ์เหล่านี้อย่างใดอย่างหนึ่งคือ ANSI / ISO SQL (ซึ่งต้องการFROM)
ypercubeᵀᴹ

ฉันไม่ได้หมายถึงการขาดfromแต่การอ้างอิงถึงcount(*)ในส่วนhavingคำสั่งโดยไม่มีข้อบ่งชี้ใด ๆ เกี่ยวกับคอลัมน์ที่จะรวมเข้าด้วยกัน สันนิษฐานว่ามันรวมกันในทุกคอลัมน์ในselectอนุประโยค
โคลิน 't ฮาร์ต

อาโอเค. ใช่ฉันยอมรับว่าเป็นสิ่งที่ทำ (รวมทุกแถวที่คุณหมายถึง - รวมทุกแถวของตารางที่ว่าง)
ypercubeᵀᴹ

4

มีการใช้เพื่อกรองกลุ่ม

โดยที่ clause ถูกใช้เพื่อกรองแถว



1
คำสั่งแรกของคุณไม่ถูกต้อง havingถูกนำไปใช้หลังจากขั้นตอนการรวมเพื่อให้สามารถใช้ในการกรองกลุ่ม
โคลิน 't ฮาร์ต

1

HAVING กำลังกรองกลุ่ม หากคุณไม่มีการจัดกลุ่มตามสาเหตุแถวทั้งหมดจะแสดงกลุ่มเดียว ดังนั้นถ้าเพรดิเคตใน HAVING ประเมินว่าเป็นจริงคุณจะได้หนึ่งแถวมิฉะนั้นจะไม่มีแถว


1

หากไม่มี GROUP BY clause เคียวรีจะพิจารณาความสัมพันธ์ทั้งหมดเป็นหนึ่งกลุ่ม

เช่น

     select count(*)
     from dual
     having count(*) > 5;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.