ทำไมคุณต้องวางคอลัมน์ที่คุณสร้างเอง (เช่น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 BYHAVING
และจะมีข้อเสียใด ๆ แทนการทำ "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เสร็จหลังจากจัดกลุ่มเสร็จแล้ว
HAVINGGROUP 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) (แซมซั่นสอนตัวเอง ... )”
มีการใช้เฉพาะกับการรวม แต่ที่มีงบไม่รวมหากคุณมีที่คำก่อนที่จะรวม (กลุ่มโดย)