นอกจากนี้ยังทำอย่างไรLEFT JOIN
, RIGHT JOIN
และFULL JOIN
พอดีมีอะไรบ้าง?
นอกจากนี้ยังทำอย่างไรLEFT JOIN
, RIGHT JOIN
และFULL JOIN
พอดีมีอะไรบ้าง?
คำตอบ:
สมมติว่าคุณกำลังเข้าร่วมในคอลัมน์ที่ไม่มีรายการซ้ำซึ่งเป็นกรณีที่พบบ่อยมาก:
การรวมภายในของ A และ B ให้ผลลัพธ์ของ A intersect B นั่นคือส่วนด้านในของจุดตัดVenn diagram
การรวมภายนอกของ A และ B ให้ผลลัพธ์ของ A union B เช่นส่วนนอกของสหภาพ Venn diagram
ตัวอย่าง
สมมติว่าคุณมีสองตารางโดยแต่ละคอลัมน์จะมีหนึ่งคอลัมน์และข้อมูลดังต่อไปนี้:
A B
- -
1 3
2 4
3 5
4 6
โปรดทราบว่า (1,2) เป็นเอกลักษณ์ของ A, (3,4) เป็นเรื่องธรรมดาและ (5,6) เป็นเอกลักษณ์ของ B
เข้าร่วมภายใน
การรวมภายในโดยใช้แบบสอบถามที่เทียบเท่าอย่างใดอย่างหนึ่งจะให้จุดตัดของตารางสองตารางนั่นคือแถวสองแถวที่พวกเขามีเหมือนกัน
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
ด้านนอกซ้ายเข้าร่วม
การรวมภายนอกด้านซ้ายจะให้แถวทั้งหมดใน A บวกกับแถวทั่วไปใน B
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
เข้าร่วมด้านนอกขวา
การรวมภายนอกด้านขวาจะให้แถวทั้งหมดใน B บวกกับแถวทั่วไปใน A
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
การรวมภายนอกเต็มรูปแบบ
การเข้าร่วมด้านนอกเต็มรูปแบบจะให้การรวม A และ B แก่คุณเช่นแถวทั้งหมดใน A และแถวทั้งหมดใน B หากบางสิ่งใน A ไม่มีตัวเลขที่สอดคล้องกันใน B ดังนั้น B ส่วนนั้นจะเป็นโมฆะ ในทางกลับกัน
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
แผนภาพเวนน์ไม่ได้ทำเพื่อฉันจริงๆ
พวกเขาไม่แสดงความแตกต่างระหว่างการเข้าร่วมไขว้และการเข้าร่วมภายในตัวอย่างเช่นหรือโดยทั่วไปจะแสดงความแตกต่างระหว่างการเข้าร่วมแบบต่างๆหรือแสดงกรอบการทำงานสำหรับเหตุผลเกี่ยวกับวิธีการทำงาน
ไม่มีสิ่งใดมาทดแทนความเข้าใจการประมวลผลเชิงตรรกะและมันค่อนข้างตรงไปตรงมาที่จะเข้าใจต่อไป
on
อนุประโยคกับแถวทั้งหมดจากขั้นตอนที่ 1 รักษาตำแหน่งที่เพรดิเคตประเมินไปtrue
(หมายเหตุ: ในทางปฏิบัติเครื่องมือเพิ่มประสิทธิภาพข้อความค้นหาอาจพบวิธีที่มีประสิทธิภาพมากขึ้นในการดำเนินการค้นหามากกว่าคำอธิบายเชิงตรรกะล้วน ๆ ข้างต้น แต่ผลลัพธ์สุดท้ายจะต้องเหมือนกัน)
ฉันจะเริ่มต้นด้วยรุ่นเคลื่อนไหวของด้านนอกเต็มรูปแบบเข้าร่วม คำอธิบายเพิ่มเติมดังนี้
ตารางที่มา
เริ่มแรกด้วยCROSS JOIN
(ผลิตภัณฑ์คาร์ทีเซียน AKA) สิ่งนี้ไม่มีส่วนON
คำสั่งและจะคืนค่าทุกชุดของแถวจากทั้งสองตาราง
เลือก A.Colour, B.Colour จาก A ข้ามเข้าร่วม
การรวมภายในและภายนอกมีส่วนคำสั่ง "ON"
เลือก A.Colour, B.Colour จากภายในเข้าร่วม B บน A.Colour = B.Colour
ข้างต้นคือการเข้าร่วม equi คลาสสิก
เงื่อนไขการรวมภายในไม่จำเป็นต้องเป็นเงื่อนไขความเสมอภาคและไม่จำเป็นต้องอ้างอิงคอลัมน์จากทั้งสอง (หรือแม้แต่) ของตาราง การประเมินผลA.Colour NOT IN ('Green','Blue')
ตอบแทนจากการเข้าร่วม cross แต่ละแถว
เลือก A.Colour, B.Colour จากภายในเข้าร่วม B ใน 1 = 1
เงื่อนไขการเข้าร่วมจะประเมินว่าเป็นจริงสำหรับทุกแถวในผลลัพธ์การเข้าร่วมไขว้ดังนั้นนี่เป็นเพียงการเข้าร่วมแบบข้าม ฉันจะไม่ทำซ้ำรูปภาพ 16 แถวอีกครั้ง
Outer Joins จะถูกประเมินอย่างมีเหตุผลในลักษณะเดียวกับ Inner joins ยกเว้นว่าถ้าแถวจากตารางด้านซ้าย (สำหรับการรวมด้านซ้าย) ไม่ได้เข้าร่วมกับแถวใด ๆ จากตารางด้านขวาเลยจะถูกเก็บไว้ในผลลัพธ์ด้วยNULL
ค่าสำหรับ คอลัมน์ทางขวามือ
นี้ก็จะ จำกัด B.Colour IS NULL
ผลก่อนหน้านี้เพียงกลับแถวที่ B
ในกรณีนี้โดยเฉพาะอย่างยิ่งเหล่านี้จะเป็นแถวที่ถูกเก็บรักษาไว้เป็นพวกเขาไม่มีการแข่งขันในตารางด้านขวามือและแบบสอบถามส่งกลับแถวสีแดงเดียวไม่ตรงกับในตาราง สิ่งนี้เรียกว่าการต่อต้านกึ่งเข้าร่วม
สิ่งสำคัญคือต้องเลือกคอลัมน์สำหรับการIS NULL
ทดสอบที่ไม่เป็นโมฆะหรือเงื่อนไขการเข้าร่วมรับรองว่าNULL
ค่าใด ๆจะถูกยกเว้นเพื่อให้รูปแบบนี้ทำงานได้อย่างถูกต้องและหลีกเลี่ยงการนำแถวกลับมาซึ่งมีNULL
ค่าสำหรับสิ่งนั้น คอลัมน์นอกเหนือจากแถวที่ไม่ตรงกัน
การรวมด้านนอกด้านขวาทำหน้าที่คล้ายกับการรวมด้านนอกด้านซ้ายยกเว้นพวกเขารักษาแถวที่ไม่ตรงกันจากตารางด้านขวาและ null จะขยายคอลัมน์ซ้ายมือ
การรวมภายนอกเต็มรูปแบบเป็นการรวมการทำงานของการรวมซ้ายและขวาและรักษาแถวที่ไม่ตรงกันจากทั้งซ้ายและตารางขวา
ไม่มีแถวในการเข้าร่วมไขว้ตรงกับเพ1=0
รดิเคต แถวทั้งหมดจากทั้งสองด้านได้รับการเก็บรักษาไว้โดยใช้กฎการเข้าร่วมด้านนอกปกติด้วย NULL ในคอลัมน์จากตารางที่อยู่อีกด้านหนึ่ง
ด้วยการแก้ไขเล็กน้อยในแบบสอบถามก่อนหน้านี้หนึ่งสามารถจำลองหนึ่งUNION ALL
ในสองตาราง
โปรดทราบว่าWHERE
ข้อ (ถ้ามี) มีเหตุผลทำงานหลังจากเข้าร่วม ข้อผิดพลาดทั่วไปอย่างหนึ่งคือการดำเนินการรวมภายนอกด้านซ้ายแล้วรวมส่วนคำสั่ง WHERE ที่มีเงื่อนไขบนตารางด้านขวาที่จบลงด้วยการยกเว้นแถวที่ไม่ตรงกัน ข้างต้นจบลงด้วยการเข้าร่วมด้านนอก ...
... จากนั้นประโยค "Where" จะทำงาน NULL= 'Green'
ไม่ได้ประเมินว่าเป็นจริงดังนั้นแถวที่เก็บรักษาไว้โดยการรวมภายนอกจะถูกยกเลิก (พร้อมด้วยสีน้ำเงิน) การแปลงการเข้าร่วมกลับเป็นแบบภายในได้อย่างมีประสิทธิภาพ
หากความตั้งใจที่จะรวมเฉพาะแถวจาก B ที่สีเป็นสีเขียวและแถวทั้งหมดจาก A โดยไม่คำนึงถึงไวยากรณ์ที่ถูกต้องจะเป็น
ดูตัวอย่างเหล่านี้ทำงานอยู่ที่ SQLFiddle.com
ตัวเชื่อมถูกใช้เพื่อรวมข้อมูลจากสองตารางกับผลลัพธ์คือตารางใหม่ชั่วคราว ตัวเชื่อมจะดำเนินการตามสิ่งที่เรียกว่าเพรดิเคตซึ่งระบุเงื่อนไขที่จะใช้เพื่อดำเนินการเข้าร่วม ความแตกต่างระหว่างการรวมภายในและการรวมภายนอกคือการเข้าร่วมภายในจะส่งกลับเฉพาะแถวที่ตรงกับจริงโดยขึ้นอยู่กับภาคแสดงการเข้าร่วม ตัวอย่างเช่นให้พิจารณาตารางพนักงานและสถานที่:
Inner Join: - Inner join สร้างตารางผลลัพธ์ใหม่โดยรวมค่าคอลัมน์ของสองตาราง (พนักงานและตำแหน่ง ) ตามการเข้าร่วมของภาคแสดง เคียวรีจะเปรียบเทียบแต่ละแถวของพนักงานกับแต่ละตำแหน่งของแถวเพื่อค้นหาคู่ของแถวทั้งหมดที่ตรงตามข้อกำหนดการเข้าร่วม เมื่อเพรดิเคตเข้าร่วมเป็นที่พอใจโดยการจับคู่ค่าที่ไม่ใช่ค่า NULL ค่าคอลัมน์สำหรับแต่ละคู่ของแถวพนักงานและตำแหน่งที่ตรงกันจะรวมกันเป็นแถวผลลัพธ์ นี่คือลักษณะที่ SQL สำหรับการเข้าร่วมภายใน:
select * from employee inner join location on employee.empID = location.empID
OR
select * from employee, location where employee.empID = location.empID
ตอนนี้นี่คือผลลัพธ์ของการรัน SQL ที่มีลักษณะดังนี้:
Outer Join: - การรวมภายนอกไม่จำเป็นต้องมีแต่ละระเบียนในตารางการรวมสองรายการเพื่อให้มีการจับคู่ที่ตรงกัน ตารางที่เข้าร่วมจะเก็บรักษาแต่ละระเบียน - แม้ว่าจะไม่มีระเบียนอื่นที่ตรงกัน การรวมด้านนอกแบ่งออกเป็นการรวมด้านนอกด้านซ้ายและการรวมภายนอกด้านขวาขึ้นอยู่กับแถวของตารางที่ถูกเก็บไว้ (ซ้ายหรือขวา)
การเข้าร่วมด้านนอกด้านซ้าย: - ผลลัพธ์ของการเข้าร่วมด้านนอกด้านซ้าย (หรือเพียงแค่การเข้าร่วมด้านซ้าย) สำหรับตารางพนักงานและตำแหน่งจะมีระเบียนทั้งหมดของตาราง "ซ้าย" (พนักงาน ) เสมอแม้ว่าเงื่อนไขการเข้าร่วมจะไม่พบระเบียนที่ตรงกัน ตาราง "ถูกต้อง" (ที่อยู่ ) นี่คือลักษณะที่ SQL สำหรับการรวมภายนอกด้านซ้ายจะมีลักษณะโดยใช้ตารางด้านบน:
select * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
ตอนนี้นี่คือผลลัพธ์ของการรัน SQL นี้ที่มีลักษณะดังนี้:
การเข้าร่วมด้านนอกด้านขวา: - การเข้าร่วมด้านนอกด้านขวา (หรือการรวมด้านขวา) คล้ายกับการเข้าร่วมด้านนอกด้านซ้ายอย่างใกล้ชิดยกเว้นการรักษาตารางที่ตรงกันข้าม ทุกแถวจากตาราง "ขวา" (ตำแหน่ง ) จะปรากฏในตารางที่เข้าร่วมอย่างน้อยหนึ่งครั้ง ถ้าไม่มีแถวที่ตรงกันจาก "ซ้าย" ตาราง (ลูกจ้าง ) มีอยู่เป็นโมฆะจะปรากฏในคอลัมน์จากพนักงานสำหรับระเบียนที่ไม่มีการแข่งขันในสถานที่ตั้ง นี่คือลักษณะของ SQL:
select * from employee right outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
เมื่อใช้ตารางด้านบนเราสามารถแสดงให้เห็นว่าชุดผลลัพธ์ของการรวมภายนอกด้านขวามีลักษณะอย่างไร:
Full Outer Joins: - Full Outer Join หรือ Full Join คือการเก็บข้อมูลที่ไม่เข้าคู่กันโดยการรวมแถวที่ไม่มีการจับคู่ในผลลัพธ์ของการเข้าร่วมให้ใช้การรวมภายนอกเต็มรูปแบบ มันรวมแถวทั้งหมดจากตารางทั้งสองโดยไม่คำนึงว่าตารางอื่นมีค่าที่ตรงกันหรือไม่
ดึงแถวที่ตรงกันเท่านั้นนั่นคือ, A intersect B
.
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
เลือกระเบียนทั้งหมดจากตารางแรกและระเบียนใด ๆ ในตารางที่สองที่ตรงกับคีย์ที่เข้าร่วม
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
เลือกระเบียนทั้งหมดจากตารางที่สองและระเบียนใด ๆ ในตารางแรกที่ตรงกับคีย์ที่เข้าร่วม
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
ในคำง่าย ๆ :
การรวมภายในดึงข้อมูลแถวที่ตรงกันเท่านั้น
ในขณะที่การรวมภายนอกดึงแถวที่ตรงกันจากตารางหนึ่งและแถวทั้งหมดในตารางอื่น .... ผลลัพธ์ขึ้นอยู่กับว่าคุณกำลังใช้อะไรอยู่:
ซ้าย : แถวที่ตรงกันในตารางด้านขวาและแถวทั้งหมดในตารางด้านซ้าย
ขวา : แถวที่ตรงกันในตารางด้านซ้ายและแถวทั้งหมดในตารางด้านขวาหรือ
เต็ม : แถวทั้งหมดในตารางทั้งหมด มันไม่สำคัญว่าจะมีการแข่งขันหรือไม่
การรวมภายในแสดงเฉพาะแถวหากมีระเบียนที่ตรงกันในอีกด้าน (ขวา) ของการเข้าร่วม
การรวมภายนอก (ซ้าย) แสดงแถวสำหรับแต่ละเร็กคอร์ดทางด้านซ้ายแม้ว่าจะไม่มีแถวที่ตรงกันในอีกด้าน (ขวา) ของการเข้าร่วม หากไม่มีแถวที่ตรงกันคอลัมน์สำหรับด้านอื่น ๆ (ขวา) จะแสดงค่า NULL
Inner joins จำเป็นต้องมีระเบียนที่มี ID ที่เกี่ยวข้องอยู่ในตารางที่เข้าร่วม
การรวมภายนอกจะส่งคืนระเบียนทางด้านซ้ายแม้ว่าจะไม่มีสิ่งใดอยู่ทางด้านขวา
ตัวอย่างเช่นคุณมีคำสั่งซื้อและตาราง OrderDetails พวกเขาเกี่ยวข้องโดย "OrderID"
สั่งซื้อ
OrderDetails
การร้องขอ
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
จะส่งคืนคำสั่งซื้อที่มีบางสิ่งบางอย่างในตาราง OrderDetails เท่านั้น
หากคุณเปลี่ยนเป็น OUTER LEFT JOIN
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
LEFT JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
จากนั้นจะส่งคืนระเบียนจากตารางคำสั่งซื้อแม้ว่าจะไม่มีระเบียน OrderDetails ก็ตาม
คุณสามารถใช้นี้เพื่อหาคำสั่งซื้อที่ไม่ได้มี OrderDetails ใด ๆ WHERE OrderDetails.OrderID IS NULL
ที่แสดงให้เห็นคำสั่งกำพร้าที่เป็นไปได้โดยการเพิ่มข้อที่เหมือน
SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
การSELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
(MySQL) กับความสำเร็จ ผมไม่แน่ใจว่าเกี่ยวกับเงื่อนไขเพิ่มเติมพวกเขาผสมกัน ...
ในคำง่าย ๆ :
การเข้าร่วมภายใน -> รับเฉพาะระเบียนทั่วไปจากตารางหลักและตารางลูกซึ่งคีย์หลักของตารางหลักตรงกับรหัสหลักในตารางย่อย
เข้าร่วมซ้าย ->
รหัสเทียม
1.Take All records from left Table
2.for(each record in right table,) {
if(Records from left & right table matching on primary & foreign key){
use their values as it is as result of join at the right side for 2nd table.
} else {
put value NULL values in that particular record as result of join at the right side for 2nd table.
}
}
เข้าร่วมขวา : ตรงข้ามกับซ้ายเข้าร่วม ใส่ชื่อของตารางใน LEFT JOIN ทางด้านขวาใน Right join คุณจะได้ผลลัพธ์เช่นเดียวกับ LEFT JOIN
ด้านนอกเข้าร่วม : No matter what
แสดงระเบียนทั้งหมดในตารางทั้งสอง ถ้าระเบียนในตารางด้านซ้ายไม่ตรงกับตารางด้านขวาตามคีย์หลักต่างประเทศให้ใช้ค่า NULL เนื่องจากการเข้าร่วม
ตัวอย่าง:
ให้สมมติว่าตอนนี้สำหรับ 2 ตาราง
1.employees , 2.phone_numbers_employees
employees : id , name
phone_numbers_employees : id , phone_num , emp_id
ที่นี่ตารางพนักงานคือตารางหลัก phone_numbers_employees เป็นตารางลูก (มีemp_id
คีย์ต่างประเทศที่เชื่อมต่อemployee.id
กับตารางลูก)
เข้าร่วมชั้นใน
ใช้บันทึก 2 ตารางเท่านั้นถ้าคีย์หลักของตารางพนักงาน (ID) ที่ตรงกับคีย์ต่างประเทศของ phone_numbers_employees ตารางเด็ก (emp_id)
ดังนั้นแบบสอบถามจะเป็น:
SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
ที่นี่ใช้เฉพาะแถวที่จับคู่บนคีย์หลัก = foreign key ตามที่อธิบายไว้ข้างต้นนี่ไม่ใช่แถวที่ตรงกันในคีย์หลัก = foreign key จะถูกข้ามไปเนื่องจากการเข้าร่วม
เข้าร่วมซ้าย :
การเข้าร่วมด้านซ้ายจะเก็บแถวทั้งหมดของตารางด้านซ้ายไว้โดยไม่คำนึงว่ามีแถวที่ตรงกับตารางด้านขวาหรือไม่
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
การรวมภายนอก :
SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
ตามลำดับดูเหมือนว่า:
คุณใช้INNER JOIN
เพื่อกลับแถวทั้งหมดจากตารางทั้งสองที่มีการแข่งขัน เช่นในตารางผลลัพธ์แถวและคอลัมน์ทั้งหมดจะมีค่า
ในOUTER JOIN
ตารางผลลัพธ์อาจมีคอลัมน์ว่าง ด้านนอกเข้าร่วมอาจจะเป็นอย่างใดอย่างหนึ่งหรือLEFT
RIGHT
LEFT OUTER JOIN
ส่งกลับแถวทั้งหมดจากตารางแรกแม้ว่าจะไม่มีการจับคู่ในตารางที่สอง
RIGHT OUTER JOIN
ส่งกลับแถวทั้งหมดจากตารางที่สองแม้ว่าจะไม่มีการจับคู่ในตารางแรก
นี่เป็นคำอธิบายไดอะแกรมที่ดีสำหรับการรวมทุกชนิด
แหล่งที่มา: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOIN
ต้องมีอย่างน้อยการแข่งขันในการเปรียบเทียบทั้งสองตาราง ตัวอย่างเช่นตาราง A และตาราง B ซึ่งแสดงถึง A ٨ B (A intersection B)
LEFT OUTER JOIN
และLEFT JOIN
เหมือนกัน มันให้ระเบียนทั้งหมดที่ตรงกันในทั้งตารางและความเป็นไปได้ทั้งหมดของตารางด้านซ้าย
ในทำนองเดียวกันRIGHT OUTER JOIN
และRIGHT JOIN
เหมือนกัน มันให้ระเบียนทั้งหมดที่ตรงกันในทั้งตารางและความเป็นไปได้ทั้งหมดของตารางด้านขวา
FULL JOIN
เป็นการรวมกันของLEFT OUTER JOIN
และRIGHT OUTER JOIN
ไม่ซ้ำซ้อน
คำตอบคือในความหมายของแต่ละคนดังนั้นในผลลัพธ์
หมายเหตุ:
ในSQLite
ไม่มีหรือRIGHT OUTER JOIN
และยังอยู่ในไม่มีFULL OUTER JOIN
MySQL
FULL OUTER JOIN
คำตอบของฉันอยู่บนพื้นฐานดังกล่าวข้างต้นหมายเหตุ
เมื่อคุณมีสองตารางดังนี้:
--[table1] --[table2]
id | name id | name
---+------- ---+-------
1 | a1 1 | a2
2 | b1 3 | b2
CROSS JOIN / OUTER JOIN:
คุณสามารถมีข้อมูลในตารางทั้งหมดด้วยCROSS JOIN
หรือแค่,
ดังนี้
SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
1 | a1 | 3 | b2
2 | b1 | 1 | a2
2 | b1 | 3 | b2
เข้าร่วมภายใน:
เมื่อคุณต้องการเพิ่มตัวกรองไปยังผลลัพธ์ด้านบนตามความสัมพันธ์แบบที่table1.id = table2.id
คุณสามารถใช้INNER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
LEFT [OUTER] JOIN:
เมื่อคุณต้องการให้มีแถวทั้งหมดของหนึ่งตารางในผลลัพธ์ข้างต้น - ด้วยความสัมพันธ์เดียวกัน - คุณสามารถใช้LEFT JOIN
:
(สำหรับRIGHT JOINเพียงเปลี่ยนสถานที่ของตาราง)
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
เข้าร่วมเต็มรูปแบบ:
เมื่อคุณต้องการมีแถวทั้งหมดของตารางอื่น ๆ ในผลลัพธ์ของคุณคุณสามารถใช้FULL OUTER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
--[Results:]
id | name | id | name
-----+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
Null | Null | 3 | b2
ดีตามความต้องการของคุณคุณเลือกแต่ละคนที่ครอบคลุมความต้องการของคุณ;)
full outer join
ใน MySQL เช่นกัน
เข้าร่วมภายใน
เข้าร่วมจะรวมแถวจากสองตาราง การเข้าร่วมภายในพยายามจับคู่สองตารางตามเกณฑ์ที่คุณระบุในแบบสอบถามและส่งคืนแถวที่ตรงกันเท่านั้น หากแถวจากตารางแรกในการเข้าร่วมตรงกับสองแถวในตารางที่สองจะมีการส่งคืนสองแถวในผลลัพธ์ หากมีแถวในตารางแรกที่ไม่ตรงกับแถวในแถวที่สองแสดงว่าไม่ได้ส่งคืน เช่นเดียวกันหากมีแถวในตารางที่สองที่ไม่ตรงกับแถวในแถวแรกก็จะไม่ถูกส่งกลับ
เข้าร่วม Outer
การเข้าร่วมด้านซ้ายพยายามค้นหาการจับคู่แถวจากตารางแรกไปยังแถวในตารางที่สอง หากไม่พบการจับคู่มันจะส่งคืนคอลัมน์จากตารางแรกและปล่อยให้คอลัมน์นั้นว่างจากตารางที่สอง (null)
INNER JOIN
เข้าร่วมโดยทั่วไปมากที่สุดสำหรับสองตารางหรือมากกว่า ส่งคืนข้อมูลที่ตรงกันทั้งบนตารางบนคีย์หลักและ forignkey ความสัมพันธ์OUTER JOIN
เหมือนกันINNER JOIN
แต่มันยังรวมถึงNULL
ข้อมูลบน ResultSet
LEFT JOIN
= INNER JOIN
+ ข้อมูลที่ไม่ตรงกันของตารางด้านซ้ายที่Null
ตรงกับตารางด้านขวาRIGHT JOIN
= INNER JOIN
+ ข้อมูลที่ไม่ตรงกันของตารางด้านขวามีข้อมูลNull
ตรงกันบนตารางด้านซ้ายFULL JOIN
= INNER JOIN
+ ข้อมูลที่ไม่ตรงกันในทั้งด้านขวาและซ้ายของตารางด้วยการNull
จับคู่INNER JOIN
และOUTER JOIN
เราสามารถเขียนแบบสอบถามเข้าร่วมด้วยตนเองตัวอย่างเช่น:
SELECT *
FROM tablea a
INNER JOIN tableb b
ON a.primary_key = b.foreign_key
INNER JOIN tablec c
ON b.primary_key = c.foreign_key
ฉันไม่เห็นรายละเอียดมากนักเกี่ยวกับประสิทธิภาพและเครื่องมือเพิ่มประสิทธิภาพในคำตอบอื่น ๆ
บางครั้งก็เป็นการดีที่จะรู้ว่าเท่านั้น INNER JOIN
เชื่อมโยงซึ่งหมายความว่าเครื่องมือเพิ่มประสิทธิภาพมีตัวเลือกมากที่สุดในการเล่นกับมัน สามารถเรียงลำดับการเข้าร่วมใหม่เพื่อให้การรักษาผลลัพธ์เดียวกันรวดเร็วขึ้น เครื่องมือเพิ่มประสิทธิภาพสามารถใช้โหมดการเข้าร่วมมากที่สุด
โดยทั่วไปแล้วเป็นวิธีปฏิบัติที่ดีในการพยายามใช้INNER JOIN
แทนที่จะเข้าร่วมประเภทอื่น (แน่นอนถ้าเป็นไปได้ให้พิจารณาชุดผลลัพธ์ที่คาดไว้)
มีตัวอย่างและคำอธิบายที่ดีเกี่ยวกับพฤติกรรมการเชื่อมโยงที่แปลกประหลาดนี้:
INNER JOIN
ช้ากว่าLEFT JOIN
ในหลายครั้งและผู้คนสามารถใช้LEFT JOIN
แทนได้INNER JOIN
โดยการเพิ่มการWHERE
ลบNULL
ผลลัพธ์ที่ไม่คาดคิด;)
INNER
ช้าลง
เมื่อได้รับการวิพากษ์วิจารณ์แผนภาพเวนน์สีแดงซึ่งเป็นที่รักมากฉันคิดว่ามันยุติธรรมที่จะโพสต์ความพยายามของฉันเอง
แม้ว่าคำตอบของ @Martin Smith นั้นดีที่สุดในกลุ่มนี้โดยทางยาวเขาจะแสดงเฉพาะคอลัมน์สำคัญจากแต่ละตารางในขณะที่ฉันคิดว่าควรจะแสดงคอลัมน์ที่ไม่สำคัญเช่นกัน
สิ่งที่ดีที่สุดที่ฉันสามารถทำได้ในครึ่งชั่วโมงที่ได้รับอนุญาตฉันยังคงไม่คิดว่ามันเพียงพอที่จะแสดงให้เห็นว่ามีโมฆะเนื่องจากไม่มีค่าคีย์ในTableB
หรือที่OUTER JOIN
จริงแล้วเป็นสหภาพแทนที่จะเข้าร่วม:
TableA a LEFT OUTER JOIN TableB b
ด้วยTableB B RIGHT OUTER JOIN TableA a
อัลกอริทึมที่แม่นยำสำหรับINNER JOIN
, LEFT/RIGHT OUTER JOIN
ดังต่อไปนี้:
a
(a, b[i])
ON ...
ข้อกับแต่ละคู่:ON( a, b[i] ) = true/false?
true
(a, b[i])
Outer Join
ส่งคืนคู่(เสมือน) ที่ใช้Null
สำหรับคอลัมน์ทั้งหมดของตารางอื่น: (a, Null)
สำหรับการเข้าร่วมด้านนอกด้านซ้ายหรือ(Null, b)
การเข้าร่วมด้านนอกขวา นี่คือเพื่อให้แน่ใจว่าแถวทั้งหมดของตารางแรกมีอยู่ในผลลัพธ์สุดท้ายหมายเหตุ:เงื่อนไขที่ระบุไว้ในON
ข้อสามารถเป็นอะไรก็ได้ไม่จำเป็นต้องใช้คีย์หลัก (และคุณไม่จำเป็นต้องอ้างถึงคอลัมน์จากตารางทั้งสองเสมอ)! ตัวอย่างเช่น:
... ON T1.title = T2.title AND T1.version < T2.version
(=> ดูโพสต์นี้เป็นการใช้งานตัวอย่าง: เลือกเฉพาะแถวที่มีค่าสูงสุดในคอลัมน์ )... ON T1.y IS NULL
... ON 1 = 0
(เช่นเดียวกับตัวอย่าง)หมายเหตุ:เข้าร่วมซ้าย = เข้าร่วมด้านนอกด้านซ้ายเข้าร่วมขวา = เข้าร่วมด้านนอกขวา
คำจำกัดความที่ง่ายที่สุด
Inner Join: ส่งกลับระเบียนที่ตรงกันจากทั้งสองตาราง
Full Outer Join: ส่งคืนระเบียนที่ตรงกันและไม่ตรงกันจากทั้งสองตารางด้วยค่า Null สำหรับระเบียนที่ไม่ตรงกันจากทั้งสองตารางตารางทั้งสอง
Left Outer Join: ส่งคืนระเบียนที่ตรงกันและไม่ตรงกันจากตารางทางด้านซ้ายเท่านั้นเท่านั้น
Right Outer Join: ส่งคืนระเบียนที่ตรงกันและไม่ตรงกันจากตารางทางด้านขวาเท่านั้นเท่านั้น
ในระยะสั้น
จับคู่ + ซ้ายตรงกันตรงกัน + ขวาตรงกัน = เต็มภายนอกเข้าร่วม
จับคู่ + ซ้ายไม่ตรงกัน = ซ้ายเข้าร่วมด้านนอก
จับคู่ + ขวาไม่ตรงกัน = นอกเข้าร่วม
จับคู่ = Inner Join
ในเงื่อนไขง่าย ๆ
1 INNER JOIN หรือ EQUI JOIN:คืนค่าผลลัพธ์ที่ตรงกับเงื่อนไขเฉพาะในตารางทั้งสอง
2 OUTER JOIN:ส่งคืน resultset ของค่าทั้งหมดจากทั้งสองตารางแม้ว่าจะมีเงื่อนไขตรงกันหรือไม่ก็ตาม
3 LEFT JOIN:ส่งคืน resultset ของค่าทั้งหมดจากตารางด้านซ้ายและเฉพาะแถวที่ตรงกับเงื่อนไขในตารางด้านขวา
4 RIGHT JOIN:ส่งคืน resultset ของค่าทั้งหมดจากตารางด้านขวาและเฉพาะแถวที่ตรงกับเงื่อนไขในตารางด้านซ้าย
5. FULL JOIN:เข้าร่วมเต็มรูปแบบและเข้าร่วมเต็มรูปแบบด้านนอกเหมือนกัน
ตัวอย่าง
สมมติว่าคุณมีสองตารางโดยแต่ละคอลัมน์จะมีหนึ่งคอลัมน์และข้อมูลดังต่อไปนี้:
A B
- -
1 3
2 4
3 5
4 6
7
8
โปรดทราบว่า (1,2,7,8) เป็นเอกลักษณ์ของ A, (3,4) เป็นเรื่องธรรมดาและ (5,6) เป็นเอกลักษณ์ของ B
คำหลัก INNER JOIN เลือกแถวทั้งหมดจากทั้งสองตารางตราบเท่าที่เงื่อนไขตรงตาม คำหลักนี้จะสร้างชุดผลลัพธ์โดยรวมแถวทั้งหมดจากทั้งสองตารางที่มีเงื่อนไขตรงตามเช่นค่าของเขตข้อมูลทั่วไปจะเหมือนกัน
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
ผลลัพธ์:
a | b
--+--
3 | 3
4 | 4
การเข้าร่วมนี้จะส่งคืนแถวทั้งหมดของตารางทางด้านซ้ายของแถวการเข้าร่วมและการจับคู่สำหรับตารางทางด้านขวาของการเข้าร่วม แถวที่ไม่มีแถวที่ตรงกันทางด้านขวาชุดผลลัพธ์จะมีค่าว่าง LEFT JOIN LEFT OUTER JOIN
ยังเป็นที่รู้จักกัน
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
ผลลัพธ์:
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
7 | null
8 | null
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
ผลลัพธ์:
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
เข้าร่วมเต็มรูปแบบ (นอก) :
FULL JOIN สร้างชุดผลลัพธ์โดยรวมผลลัพธ์ของ LEFT JOIN และ RIGHT JOIN ชุดผลลัพธ์จะมีแถวทั้งหมดจากทั้งสองตาราง แถวที่ไม่มีการจับคู่ชุดผลลัพธ์จะมีค่าเป็นศูนย์
select * from a FULL OUTER JOIN b on a.a = b.b;
ผลลัพธ์:
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
7 | null
8 | null
การรวมภายใน - การรวมภายในโดยใช้แบบสอบถามที่เท่ากันอย่างใดอย่างหนึ่งจะให้จุดตัดของทั้งสองตารางคือสองแถวที่พวกเขามีร่วมกัน
การเข้าร่วมด้านนอกด้านซ้าย - การเข้าร่วมด้านนอกด้านซ้ายจะให้ทุกแถวใน A รวมถึงแถวทั่วไปใน B
การรวมภายนอกเต็มรูปแบบ - การรวมภายนอกเต็มรูปแบบจะทำให้คุณมีการรวมกันของ A และ B เช่นแถวทั้งหมดใน A และแถวทั้งหมดใน B หากบางสิ่งใน A ไม่มีตัวเลขที่สอดคล้องกันใน B ส่วน B คือ เป็นโมฆะและในทางกลับกัน
Join is not an intersection unless the tables have the same columns
หมายเลขบัญชีของคุณคุณสามารถเข้าร่วมคอลัมน์ใด ๆ ที่คุณต้องการและหากการจับคู่ค่าพวกเขาจะเข้าร่วมด้วยกัน
1. Inner Join:เรียกอีกอย่างว่าเข้าร่วม ส่งคืนแถวที่ปรากฏในทั้งตารางซ้ายและตารางด้านขวาเฉพาะในกรณีที่มีการแข่งขันถ้ามีการแข่งขันมิฉะนั้นจะส่งคืนระเบียนศูนย์
ตัวอย่าง:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
2. Full Outer Join:เรียกอีกอย่างว่า Full Join มันจะส่งคืนแถวทั้งหมดอยู่ในทั้งตารางซ้ายและตารางด้านขวา
ตัวอย่าง:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
3. ซ้ายเข้าร่วมภายนอก:หรือเรียกง่ายๆว่า Left Join ส่งคืนแถวทั้งหมดที่มีในตารางด้านซ้ายและแถวที่ตรงกันจากตารางด้านขวา (ถ้ามี)
4. Right Outer Join:เรียกอีกอย่างว่า Right Join มันส่งกลับแถวที่ตรงกันจากตารางด้านซ้าย (ถ้ามี) และแถวทั้งหมดที่มีอยู่ในตารางด้านขวา
ข้อดีของการเข้าร่วม
พิจารณาตารางด้านล่าง 2:
EMP
empid name dept_id salary
1 Rob 1 100
2 Mark 1 300
3 John 2 100
4 Mary 2 300
5 Bill 3 700
6 Jose 6 400
สาขา
deptid name
1 IT
2 Accounts
3 Security
4 HR
5 R&D
ส่วนใหญ่เขียนเป็นเพียงเข้าร่วมในแบบสอบถาม SQL มันจะส่งกลับเฉพาะระเบียนที่ตรงกันระหว่างตาราง
Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
ดังที่คุณเห็นด้านบนJose
จะไม่ถูกพิมพ์จากEMPในเอาต์พุตเนื่องจาก dept_id 6
ไม่พบข้อมูลที่ตรงกันในตารางแผนก ในทำนองเดียวกันHR
และR&D
แถวจะไม่ถูกพิมพ์จากตารางแผนกเนื่องจากไม่พบข้อมูลที่ตรงกันในตาราง Emp
ดังนั้นเข้าร่วมภายในหรือเพียงเข้าร่วมส่งคืนแถวที่ตรงกันเท่านั้น
สิ่งนี้จะส่งกลับระเบียนทั้งหมดจากตารางซ้ายและเฉพาะระเบียนที่ตรงกันจากตารางขวา
Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
6 Jose
ดังนั้นหากคุณสังเกตเห็นผลลัพธ์ข้างต้นระเบียนทั้งหมดจากตารางซ้าย (Emp) จะถูกพิมพ์ด้วยการจับคู่ระเบียนจากตาราง RIGHT
HR
และR&D
แถวจะไม่ถูกพิมพ์จากตารางแผนกเนื่องจากไม่พบข้อมูลที่ตรงกันในตาราง Emp ที่ dept_id
ดังนั้น LEFT JOIN ส่งคืนแถวทั้งหมดจากตารางด้านซ้ายและเฉพาะแถวที่ตรงกันจากตาราง RIGHT
โปรดดูคำตอบโดยมาร์ตินสมิ ธสำหรับ illustations ที่ดีกว่าและคำอธิบายที่แตกต่างกันเข้าร่วมรวมทั้งและโดยเฉพาะอย่างยิ่งความแตกต่างระหว่างFULL OUTER JOIN
, และRIGHT OUTER JOIN
LEFT OUTER JOIN
ตารางทั้งสองนี้เป็นพื้นฐานสำหรับการเป็นตัวแทนของJOIN
s ด้านล่าง:
SELECT *
FROM citizen
CROSS JOIN postalcode
ผลลัพธ์จะเป็นผลิตภัณฑ์คาร์ทีเซียนของชุดค่าผสมทั้งหมด ไม่JOIN
ต้องการเงื่อนไข:
INNER JOIN
เหมือนกันเพียง: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
ผลลัพธ์จะเป็นชุดค่าผสมที่ตรงตามJOIN
เงื่อนไขที่ต้องการ:
LEFT OUTER JOIN
เป็นเช่นเดียวกับ LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
ผลลัพธ์จะเป็นทุกอย่างcitizen
แม้ว่าจะไม่มีการแข่งขันpostalcode
ก็ตาม ต้องมีJOIN
เงื่อนไขอีกครั้ง:
ตัวอย่างทั้งหมดถูกรันบน Oracle 18c มีวางจำหน่ายแล้วที่dbfiddle.ukซึ่งเป็นที่จับภาพหน้าจอของตาราง
CREATE TABLE citizen (id NUMBER,
name VARCHAR2(20),
postal NUMBER, -- <-- could do with a redesign to postalcode.id instead.
leader NUMBER);
CREATE TABLE postalcode (id NUMBER,
postal NUMBER,
city VARCHAR2(20),
area VARCHAR2(20));
INSERT INTO citizen (id, name, postal, leader)
SELECT 1, 'Smith', 2200, null FROM DUAL
UNION SELECT 2, 'Green', 31006, 1 FROM DUAL
UNION SELECT 3, 'Jensen', 623, 1 FROM DUAL;
INSERT INTO postalcode (id, postal, city, area)
SELECT 1, 2200, 'BigCity', 'Geancy' FROM DUAL
UNION SELECT 2, 31006, 'SmallTown', 'Snizkim' FROM DUAL
UNION SELECT 3, 31006, 'Settlement', 'Moon' FROM DUAL -- <-- Uuh-uhh.
UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space' FROM DUAL;
JOIN
และWHERE
CROSS JOIN
ส่งผลให้แถวเป็นแนวคิดทั่วไป / INNER JOIN
:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows
การใช้CROSS JOIN
เพื่อให้ได้ผลลัพธ์ของLEFT OUTER JOIN
กลวิธีที่ต้องการเพิ่มในNULL
แถว มันถูกละไว้
INNER JOIN
กลายเป็นผลิตภัณฑ์คาร์ทีเซียน มันเหมือนกับแนวคิดทั่วไป / CROSS JOIN
:
SELECT *
FROM citizen c
JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
นี่คือจุดที่สามารถเห็นการรวมภายในเป็นการรวมข้ามกับผลลัพธ์ที่ไม่ตรงกับเงื่อนไขที่ถูกลบออก ที่นี่ไม่มีแถวผลลัพธ์ถูกลบออก
ใช้INNER JOIN
เพื่อให้ได้ผลลัพธ์ของการLEFT OUTER JOIN
ยังต้องใช้เทคนิค มันถูกละไว้
LEFT JOIN
ผลลัพธ์เป็นแถวตามแนวคิดทั่วไป / CROSS JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
LEFT JOIN
ผลลัพธ์เป็นแถวตามแนวคิดทั่วไป / INNER JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode
การค้นหารูปภาพทางอินเทอร์เน็ตที่ "sql join cross outer outer outer" จะแสดงไดอะแกรมของ Venn มากมาย ฉันเคยมีสำเนาที่พิมพ์บนโต๊ะของฉัน แต่มีปัญหาเกี่ยวกับการเป็นตัวแทน
ไดอะแกรมเวนน์นั้นยอดเยี่ยมสำหรับทฤษฎีเซตซึ่งองค์ประกอบสามารถอยู่ในเซตเดียวหรือทั้งคู่ก็ได้ แต่สำหรับฐานข้อมูลแล้วองค์ประกอบใน "set" ดูเหมือนจะเป็นแถวในตารางและดังนั้นจึงไม่ปรากฏในตารางอื่น ๆ ไม่มีสิ่งใดเหมือนแถวหนึ่งที่ปรากฏในหลายตาราง แถวเป็นตารางเฉพาะ
การรวมตัวเองเป็นกรณีมุมที่แต่ละองค์ประกอบมีความเหมือนกันในทั้งสองชุด แต่ก็ยังไม่มีปัญหาใด ๆ ด้านล่าง
ชุดA
หมายถึงชุดทางด้านซ้าย ( citizen
ตาราง) และชุดB
เป็นชุดทางด้านขวา ( postalcode
ตาราง) ในการสนทนาด้านล่าง
ทุกองค์ประกอบในทั้งสองชุดจะถูกจับคู่กับทุกองค์ประกอบในอีกชุดหนึ่งซึ่งหมายความว่าเราต้องการA
ปริมาณของทุกB
องค์ประกอบและB
จำนวนของทุกA
องค์ประกอบเพื่อแสดงผลิตภัณฑ์คาร์ทีเซียนนี้อย่างเหมาะสม ทฤษฎีเซตไม่ได้ถูกสร้างขึ้นสำหรับองค์ประกอบที่เหมือนกันหลายชุดในชุดดังนั้นฉันจึงพบว่าไดอะแกรมของเวนน์แสดงให้เห็นอย่างถูกต้องว่าเป็นไปไม่ได้ / เป็นไปไม่ได้ ดูเหมือนจะไม่เป็นเช่นนั้นUNION
เหมาะเลย
แถวนั้นแตกต่างกัน UNION
คือ 7 แถวในทั้งหมด แต่ไม่สามารถใช้ร่วมกับSQL
ชุดผลลัพธ์ทั่วไปได้ และนี่ไม่ใช่วิธีการCROSS JOIN
ทำงานทั้งหมด:
พยายามเป็นตัวแทนของมันเช่นนี้:
..but ตอนนี้มันก็ดูเหมือนว่าINTERSECTION
ซึ่งก็แน่นอนไม่ได้ นอกจากนี้ยังไม่มีองค์ประกอบในสิ่งINTERSECTION
ที่อยู่ในชุดที่แตกต่างกันสองชุด อย่างไรก็ตามดูเหมือนว่าผลลัพธ์ที่ค้นหาได้จะคล้ายกับสิ่งนี้มาก:
สำหรับการอ้างอิงหนึ่งผลค้นหาสำหรับCROSS JOIN
s สามารถมองเห็นที่Tutorialgateway INTERSECTION
เช่นเดียวกับคนนี้เป็นที่ว่างเปล่า
ค่าขององค์ประกอบขึ้นอยู่กับJOIN
เงื่อนไข เป็นไปได้ที่จะแสดงสิ่งนี้ภายใต้เงื่อนไขว่าทุกแถวจะมีลักษณะเฉพาะกับเงื่อนไขนั้น ความหมายid=x
เป็นจริงสำหรับหนึ่งแถวเท่านั้น เมื่อแถวในตารางA
( citizen
) ตรงกับหลายแถวในตารางB
( postalcode
) ภายใต้JOIN
เงื่อนไขผลลัพธ์จะมีปัญหาเช่นเดียวกับCROSS JOIN
: แถวจะต้องแสดงหลาย ๆ ครั้งและทฤษฎีเซตไม่ได้ถูกสร้างขึ้นมาเพื่อสิ่งนั้นจริงๆ ภายใต้เงื่อนไขของความเป็นเอกลักษณ์แผนภาพอาจทำงานได้ แต่โปรดจำไว้ว่าJOIN
เงื่อนไขนั้นจะกำหนดตำแหน่งขององค์ประกอบในแผนภาพ ดูเฉพาะค่าของJOIN
สภาพที่มีกับส่วนที่เหลือของแถวพร้อมสำหรับการนั่ง:
การแสดงนี้ตกอยู่ห่างกันอย่างสมบูรณ์เมื่อใช้INNER JOIN
กับสภาพที่ทำให้มันเป็นON 1 = 1
CROSS JOIN
ด้วยตัวเอง - JOIN
แถวต่างๆเป็นองค์ประกอบตัวตนที่เป็นจริงในทั้งสองตาราง แต่แสดงถึงตารางว่าทั้งสองA
และB
ไม่เหมาะสมมาก ตัวอย่างเช่นJOIN
เงื่อนไขทั่วไปที่ทำให้องค์ประกอบในA
การจับคู่องค์ประกอบที่แตกต่างใน B คือON A.parent = B.child
การจับคู่จากA
ไปยังB
องค์ประกอบแยกต่างหาก จากตัวอย่างที่เป็นSQL
เช่นนี้:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
ความหมายสมิ ธ เป็นผู้นำของทั้งกรีนและเซ่น
ปัญหาเริ่มต้นอีกครั้งเมื่อแถวหนึ่งมีการจับคู่หลายแถวกับอีกแถวในตารางอื่น นี่คือความซับซ้อนต่อไปเพราะOUTER JOIN
สามารถที่จะตรงกับชุดที่ว่างเปล่า แต่ในการตั้งทฤษฎีสหภาพของชุดใด ๆและชุดที่ว่างเปล่าอยู่เสมอเพียงC
C
ชุดที่ว่างเปล่าไม่เพิ่มอะไรเลย การเป็นตัวแทนของสิ่งนี้LEFT OUTER JOIN
มักจะแสดงให้ทุกคนA
เห็นว่าแถวในA
นั้นถูกเลือกไม่ว่าจะมีการแข่งขันหรือไม่B
ก็ตาม อย่างไรก็ตาม "องค์ประกอบการจับคู่" มีปัญหาเช่นเดียวกับภาพประกอบด้านบน ขึ้นอยู่กับเงื่อนไข และชุดที่ว่างเปล่าดูเหมือนจะเดินไปที่A
:
ค้นหาแถวทั้งหมดจาก a CROSS JOIN
ด้วย Smith และรหัสไปรษณีย์บนดวงจันทร์:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
JOIN
ตอนนี้แผนภาพเวนน์ไม่ได้ใช้เพื่อสะท้อนให้เห็นถึง มันใช้สำหรับข้อเท่านั้นWHERE
:
.. และนั่นทำให้รู้สึก
ตามที่ได้อธิบายไม่ได้จริงๆINNER JOIN
INTERSECT
อย่างไรก็ตามINTERSECT
s สามารถใช้กับผลลัพธ์ของข้อความค้นหาแยกต่างหาก นี่คือไดอะแกรมเวนน์เหมาะสมแล้วเนื่องจากองค์ประกอบจากคิวรีแบบแยกเป็นแถวที่จริงซึ่งเป็นของผลลัพธ์ใดผลลัพธ์หนึ่งหรือทั้งสองอย่าง จุดตัดจะส่งกลับเฉพาะผลลัพธ์ที่มีแถวอยู่ในข้อความค้นหาทั้งสอง สิ่งนี้SQL
จะส่งผลให้แถวเดียวกันกับด้านบนWHERE
และแผนภาพเวนน์จะเหมือนกัน:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
INTERSECT
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
OUTER JOIN
UNION
ไม่ได้เป็น อย่างไรก็ตามUNION
ทำงานภายใต้เงื่อนไขเดียวกันINTERSECT
ซึ่งทำให้ได้ผลลัพธ์ทั้งหมดที่รวมทั้งSELECT
s:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
UNION
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
ซึ่งเทียบเท่ากับ:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
.. และให้ผลลัพธ์:
นอกจากนี้ที่นี่แผนภาพเวนน์ทำให้รู้สึก:
หมายเหตุสำคัญคือเหล่านี้ทำงานเฉพาะเมื่อโครงสร้างของผลที่ได้จากทั้งสองเลือกที่จะเหมือนกันที่ช่วยให้การเปรียบเทียบหรือสหภาพแรงงาน ผลลัพธ์ของทั้งสองนี้จะไม่เปิดใช้งานว่า:
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
.. พยายามรวมผลลัพธ์ด้วยการUNION
ให้
ORA-01790: expression must have same datatype as corresponding expression
ที่ให้ความสนใจต่อการอ่านบอกว่าไม่มีการแผนภาพเวนน์เมื่ออธิบายร่วมและSQL ร่วมเป็นแผนภาพเวนน์ EXCEPT
ทั้งยังปก
มีคำตอบที่ดีมากมายที่นี่พร้อมตัวอย่างพีชคณิตเชิงสัมพันธ์ที่แม่นยำมาก นี่เป็นคำตอบที่ง่ายมากที่อาจเป็นประโยชน์สำหรับมือสมัครเล่นหรือผู้เริ่มหัดใช้ด้วยรหัสวิกฤติ SQL
โดยทั่วไปบ่อยกว่าไม่แบบสอบถามJOIN
เดือดลงไปสองกรณี:
สำหรับSELECT
ชุดย่อยของข้อมูลA
:
INNER JOIN
เมื่อข้อมูลที่เกี่ยวข้องB
คุณกำลังมองหาต้องมีอยู่ต่อการออกแบบฐานข้อมูล;LEFT JOIN
เมื่อข้อมูลที่เกี่ยวข้องที่B
คุณกำลังมองหาMIGHTหรือMIGHT ไม่มีอยู่ต่อการออกแบบฐานข้อมูลความแตกต่างระหว่างinner join
และouter join
เป็นดังนี้:
Inner join
เป็นการรวมที่รวมตารางตาม tuples ที่ตรงกันในขณะที่outer join
เป็นการรวมที่รวมตารางตาม tuple ทั้งที่ตรงกันและไม่ตรงกันInner join
ผสานแถวที่ตรงกันจากสองตารางที่ละเว้นแถวที่ไม่ตรงกันในขณะที่outer join
ผสานแถวจากสองตารางและแถวที่ไม่ตรงกันจะเติมด้วยค่า nullInner join
เป็นเหมือนการดำเนินการทางแยกในขณะที่outer join
เป็นเหมือนการดำเนินการสหภาพInner join
เป็นสองประเภทในขณะที่outer join
สามประเภทouter join
inner join
จะเร็วกว่า