แบบสอบถามที่ซ้อนกันใน SQL
ภาษา SQL ช่วยให้คุณสามารถซ้อนหนึ่งแบบสอบถามภายในแบบสอบถามอื่น สิ่งนี้ทำให้สามารถเขียนเคียวรีขนาดใหญ่มากหนึ่งรายการที่จะทำบางสิ่งที่ใหญ่และซับซ้อนได้ แม้ว่าความสามารถในการอ่านโค้ดจะลดลงอย่างมากก็ตาม
พื้นที่ที่สามารถใช้การเปลี่ยนแปลงขึ้นอยู่กับจำนวนค่าที่ส่งคืนโดยแบบสอบถามย่อย มีทั้งหมดสามตัวเลือก:
- แบบสอบถามย่อยส่งกลับหนึ่งค่าเดียว (หนึ่งคอลัมน์และหนึ่งแถว)
- แบบสอบถามย่อยส่งคืนรายการค่า (ตารางที่มีหนึ่งคอลัมน์)
- ข้อความค้นหาย่อยส่งคืนตาราง (หลายคอลัมน์ จำนวนแถวเท่าใดก็ได้)
ลองดูตัวอย่างสำหรับแต่ละกรณี
แบบสอบถามย่อยที่มีผลสเกลาร์
มาดูรายชื่อพนักงานทั้งหมดของเราจากตารางพนักงานที่มีเงินเดือนสูงกว่าค่าเฉลี่ยของบริษัทกัน เราจะทำได้อย่างไร?
เราสามารถกรองพนักงานได้อย่างง่ายดายโดยการเปรียบเทียบเงินเดือนกับค่าเฉลี่ยหากเราทราบล่วงหน้า ในเวลาเดียวกันเราได้เขียนแบบสอบถามที่ช่วยให้เราสามารถคำนวณเงินเดือนเฉลี่ยของพนักงานของ บริษัท ได้ จำไว้:
SELECT AVG(salary) FROM employee
จากนั้น MySQL คืนค่าให้เรา: 76833.3333
จะหารายชื่อพนักงานทุกคนที่เงินเดือนสูงกว่าค่าเฉลี่ยได้อย่างไร นอกจากนี้ยังง่ายมาก:
SELECT * FROM employee
WHERE salary > 76833.3333
ผลลัพธ์ของแบบสอบถามนี้จะเป็น:
รหัส | ชื่อ | อาชีพ | เงินเดือน |
---|---|---|---|
1 | อีวานอฟ อีวาน | โปรแกรมเมอร์ | 100,000 |
2 | เปตรอฟ เปตรอฟ | โปรแกรมเมอร์ | 80000 |
4 | ราบิโนวิช มอยชา | ผู้อำนวยการ | 200,000 |
และตอนนี้เราเพิ่งรวมคำขอทั้งสองโดยแทนที่คำขอแรกแทนค่า 76833:
SELECT * FROM employee
WHERE salary > (SELECT AVG(salary) FROM employee)
ผลลัพธ์ของแบบสอบถามนี้จะเหมือนกัน:
รหัส | ชื่อ | อาชีพ | เงินเดือน |
---|---|---|---|
1 | อีวานอฟ อีวาน | โปรแกรมเมอร์ | 100,000 |
2 | เปตรอฟ เปตรอฟ | โปรแกรมเมอร์ | 80000 |
4 | ราบิโนวิช มอยชา | ผู้อำนวยการ | 200,000 |
แบบสอบถามย่อยพร้อมรายการค่า
คุณจำได้ไหมว่าครั้งหนึ่งเราเคยทำงาน - เพื่อค้นหาบันทึกทั้งหมดจากตารางหนึ่งซึ่งไม่มีบันทึกที่สอดคล้องกันจากอีกตารางหนึ่ง
มีภาพนี้ด้วย:
![](https://cdn.codegym.cc/images/article/a0eff64c-0bb4-4480-833e-c1305cd03a5e/512.jpeg)
ถ้าจำไม่ผิด งานจะเป็นดังนี้: แสดง ราย ชื่อพนักงานทั้งหมดจากตารางพนักงานที่ไม่มีงานในตารางงาน
เรามาหาทางออกในสองขั้นตอนกัน
ขั้นแรก ให้เขียนแบบสอบถามที่จะส่งคืนรหัสของพนักงานทุกคนที่มีงานในตารางงาน เพียงจำสองสิ่ง:
- ลบรายการที่ซ้ำกัน - ใช้คำหลัก DISTINCT
- ลบค่า NULL ออกจากผลลัพธ์
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
และที่นี่เราได้ผลลัพธ์ที่สวยงามจากคำขอดังกล่าว:
รหัสพนักงาน |
---|
1 |
2 |
5 |
4 |
6 |
ขอจดชั่วคราวเพื่อความสะดวกตามลำดับ: 1,2,5,4,6 ตอนนี้มาเขียนแบบสอบถามที่สอง - ไปที่ตารางพนักงานซึ่งจะส่งคืนรายชื่อพนักงานที่ไม่มีรหัสอยู่ในรายการแรก:
SELECT * FROM employee
WHERE id NOT IN (1,2,5,4,6)
และผลลัพธ์ของแบบสอบถามนี้:
รหัส | ชื่อ | อาชีพ | เงินเดือน | อายุ | เข้าร่วม_วันที่ |
---|---|---|---|---|---|
3 | อีวานอฟ เซอร์เกย์ | เทสเตอร์ | 40000 | สามสิบ | 2014-01-01 |
และในตอนนี้ เช่นเดียวกับในตัวอย่างก่อนหน้านี้ คุณสามารถรวมคำขอทั้งสองได้โดยเพียงแค่แทนที่เนื้อหาของคำขอแรกแทนรายการ id
SELECT * FROM employee
WHERE id NOT IN (
SELECT DISTINCT employee_id FROM task
WHERE employee_id IS NOT NULL
)