ทำไมคุณต้องวางคอลัมน์ที่คุณสร้างเอง (เช่นselect 1 as "number"
) หลังHAVING
และไม่WHERE
อยู่ใน MySQL?
และมีข้อเสียใด ๆ แทนการทำWHERE 1
(เขียนคำจำกัดความทั้งหมดแทนชื่อคอลัมน์)?
ทำไมคุณต้องวางคอลัมน์ที่คุณสร้างเอง (เช่นselect 1 as "number"
) หลังHAVING
และไม่WHERE
อยู่ใน MySQL?
และมีข้อเสียใด ๆ แทนการทำWHERE 1
(เขียนคำจำกัดความทั้งหมดแทนชื่อคอลัมน์)?
คำตอบ:
ทำไมคุณต้องวางคอลัมน์ที่คุณสร้างขึ้นมาเอง (เช่น "เลือก 1 เป็นหมายเลข") หลังจากที่มีและไม่ใช่ที่ใน MySQL?
WHERE
ก่อนที่จะถูกนำไปใช้GROUP BY
, HAVING
ถูกนำไปใช้หลังจาก (และสามารถกรองมวลรวม)
โดยทั่วไปแล้วคุณสามารถอ้างอิงนามแฝงในค่าของคำสั่งเหล่านี้ แต่MySQL
ช่วยให้การอ้างอิงSELECT
นามแฝงในระดับGROUP BY
, และORDER BY
HAVING
และจะมีข้อเสียใด ๆ แทนการทำ "WHERE 1" (เขียนคำจำกัดความทั้งหมดแทนชื่อคอลัมน์)
หากนิพจน์ที่คำนวณได้ของคุณไม่มีการรวมใด ๆ การวางลงในส่วนWHERE
คำสั่งอาจมีประสิทธิภาพมากขึ้น
คำตอบอื่น ๆ ทั้งหมดสำหรับคำถามนี้ไม่ได้ตอบโจทย์ประเด็นสำคัญ
สมมติว่าเรามีโต๊ะ:
CREATE TABLE `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`value` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
และมี 10 แถวที่มีทั้ง id และค่าจาก 1 ถึง 10:
INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);
ลอง 2 แบบสอบถามต่อไปนี้:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
คุณจะได้ผลลัพธ์ที่เหมือนกันทุกประการคุณจะเห็นว่าส่วนคำสั่ง HAVING สามารถทำงานได้โดยไม่มี GROUP BY clause
นี่คือความแตกต่าง:
SELECT `value` v FROM `table` WHERE `v`>5;
ข้อผิดพลาด # 1054 - คอลัมน์ที่ไม่รู้จัก 'v' ใน 'where clause'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
ส่วนคำสั่ง WHERE อนุญาตให้เงื่อนไขใช้คอลัมน์ตารางใด ๆ แต่ไม่สามารถใช้นามแฝงหรือฟังก์ชันการรวม ส่วนคำสั่ง HAVING อนุญาตให้เงื่อนไขใช้คอลัมน์ (!) ที่เลือกไว้นามแฝงหรือฟังก์ชันการรวม
นี่เป็นเพราะ WHERE ส่วนคำสั่งกรองข้อมูลก่อนที่จะเลือก แต่ HAVING ข้อกรองผลข้อมูลหลังจากเลือก
ดังนั้นให้วางเงื่อนไขในส่วนคำสั่ง WHERE ซึ่งจะมีประสิทธิภาพมากกว่าถ้าคุณมีหลายแถวในตาราง
ลองอธิบายเพื่อดูความแตกต่างที่สำคัญ:
EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| 1 | SIMPLE | table | range | value | value | 4 | NULL | 5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| 1 | SIMPLE | table | index | NULL | value | 4 | NULL | 10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
คุณสามารถดูได้ว่า WHERE หรือ HAVING ใช้ดัชนี แต่แถวนั้นแตกต่างกัน
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
...HAVING clause can use either column or alias.
...WHERE clause will be more effective
...WHERE clause will be more efficient
ข้อแตกต่างที่สำคัญคือWHERE
ไม่สามารถใช้กับรายการที่จัดกลุ่ม (เช่นSUM(number)
) โดยที่HAVING
สามารถทำได้
เหตุผลคือWHERE
ทำก่อนการจัดกลุ่มและHAVING
เสร็จหลังจากจัดกลุ่มเสร็จแล้ว
HAVING
GROUP BY
จะใช้ในการกรองรวมตัวในของคุณ
ตัวอย่างเช่นหากต้องการตรวจสอบชื่อที่ซ้ำกัน:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
ทั้งสองนี้จะรู้สึกเหมือนเป็นครั้งแรกที่ทั้งคู่ถูกใช้เพื่อกล่าวถึงเงื่อนไขในการกรองข้อมูล แม้ว่าเราสามารถใช้ 'มี' แทนที่ 'ที่ไหน' ในกรณีใด ๆ มีกรณีที่เราไม่สามารถใช้ 'ที่ไหน' แทน 'มี' นี่เป็นเพราะในแบบสอบถามแบบใช้เลือกข้อมูล 'ซึ่ง' กรองข้อมูลก่อน 'เลือก' ในขณะที่ 'มี' กรองข้อมูลหลังจาก 'เลือก' ดังนั้นเมื่อเราใช้ชื่อนามแฝงที่ไม่ได้อยู่ในฐานข้อมูล 'ที่' ไม่สามารถระบุได้ แต่ 'มี' สามารถ
ตัวอย่าง: ให้ตารางนักเรียนมี student_id, ชื่อ, วันเกิด, ที่อยู่วันเกิดสมมติว่าเป็นวันที่พิมพ์
SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/
SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20;
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/
WHERE
HAVING
ตัวกรองWHEREก่อนที่ข้อมูลจะถูกจัดกลุ่มและตัวกรองHAVINGหลังจากข้อมูลถูกจัดกลุ่ม นี่คือความแตกต่างที่สำคัญ แถวที่ถูกกำจัดโดยส่วนคำสั่ง WHEREจะไม่รวมอยู่ในกลุ่ม สิ่งนี้สามารถเปลี่ยนค่าที่คำนวณได้ซึ่งในทางกลับกัน (= เป็นผลลัพธ์) อาจส่งผลต่อกลุ่มที่ถูกกรองตามการใช้ค่าเหล่านั้นในส่วน คำสั่งHAVING
และยังคง
การมีเพื่อให้คล้ายกับสถานที่ที่ DBMSs ที่สุดรักษาพวกเขาเป็นสิ่งเดียวกันหากไม่มีกลุ่มตามที่ระบุไว้ อย่างไรก็ตามคุณควรสร้างความแตกต่างด้วยตัวคุณเอง ใช้HAVINGร่วมกับGROUP BY clauses เท่านั้น ใช้WHEREสำหรับการกรองระดับแถวมาตรฐาน
ตัดตอนมาจาก: Forta, Ben “ แซมสอนตัวเอง SQL ใน 10 นาที (ฉบับที่ 5) (แซมซั่นสอนตัวเอง ... )”
มีการใช้เฉพาะกับการรวม แต่ที่มีงบไม่รวมหากคุณมีที่คำก่อนที่จะรวม (กลุ่มโดย)