เพื่อที่จะใช้HAVING
ในการสืบค้น SQL จะต้องมีการGROUP BY
รวมชื่อคอลัมน์หรือไม่
มีกรณีพิเศษที่สามารถใช้งานได้HAVING
โดยไม่ต้องมีGROUP BY
แบบสอบถาม SQL หรือไม่?
พวกเขาจะต้องอยู่ร่วมกันในเวลาเดียวกันหรือไม่?
เพื่อที่จะใช้HAVING
ในการสืบค้น SQL จะต้องมีการGROUP BY
รวมชื่อคอลัมน์หรือไม่
มีกรณีพิเศษที่สามารถใช้งานได้HAVING
โดยไม่ต้องมีGROUP BY
แบบสอบถาม SQL หรือไม่?
พวกเขาจะต้องอยู่ร่วมกันในเวลาเดียวกันหรือไม่?
คำตอบ:
เลขที่
พวกเขาไม่จำเป็นต้องอยู่ร่วมกันดังที่พิสูจน์แล้วโดยความจริงที่ว่าแบบสอบถามต่อไปนี้ใน 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
เฟส
select 1 having count(*) = 1;
ซึ่งฉันยังไม่เข้าใจ
SELECT 1 AS id, 'Colin' AS name;
ในขณะที่คนอื่น ๆ เช่น Oracle มีdual
ตารางพิเศษ ฉันไม่คิดว่าไวยากรณ์เหล่านี้อย่างใดอย่างหนึ่งคือ ANSI / ISO SQL (ซึ่งต้องการFROM
)
from
แต่การอ้างอิงถึงcount(*)
ในส่วนhaving
คำสั่งโดยไม่มีข้อบ่งชี้ใด ๆ เกี่ยวกับคอลัมน์ที่จะรวมเข้าด้วยกัน สันนิษฐานว่ามันรวมกันในทุกคอลัมน์ในselect
อนุประโยค
มีการใช้เพื่อกรองกลุ่ม
โดยที่ clause ถูกใช้เพื่อกรองแถว
having
ถูกนำไปใช้หลังจากขั้นตอนการรวมเพื่อให้สามารถใช้ในการกรองกลุ่ม
HAVING กำลังกรองกลุ่ม หากคุณไม่มีการจัดกลุ่มตามสาเหตุแถวทั้งหมดจะแสดงกลุ่มเดียว ดังนั้นถ้าเพรดิเคตใน HAVING ประเมินว่าเป็นจริงคุณจะได้หนึ่งแถวมิฉะนั้นจะไม่มีแถว
หากไม่มี GROUP BY clause เคียวรีจะพิจารณาความสัมพันธ์ทั้งหมดเป็นหนึ่งกลุ่ม
เช่น
select count(*)
from dual
having count(*) > 5;
SELECT MIN(a) AS mina, MAX(a) As maxa FROM mytable HAVING MIN(a) < MAX(a);