ฉันสงสัยว่าจะสร้างความแตกต่างให้กับการรวมเหล่านี้ได้อย่างไร
ฉันสงสัยว่าจะสร้างความแตกต่างให้กับการรวมเหล่านี้ได้อย่างไร
คำตอบ:
ตัวอย่างง่าย ๆ : สมมติว่าคุณมีStudents
ตารางและLockers
ตาราง ใน SQL ตารางแรกที่คุณระบุในการเข้าร่วมStudents
เป็นตารางซ้ายและตารางที่สองLockers
คือตารางขวา
นักเรียนแต่ละคนสามารถได้รับมอบหมายให้ล็อกเกอร์ดังนั้นจึงมีLockerNumber
คอลัมน์ในStudent
ตาราง อาจมีนักเรียนมากกว่าหนึ่งคนที่อยู่ในตู้เก็บของเดียว แต่โดยเฉพาะอย่างยิ่งในช่วงต้นปีการศึกษาคุณอาจมีนักเรียนที่เข้ามาโดยไม่มีตู้เก็บของและตู้เก็บของบางตู้ที่ไม่มีนักเรียนมอบหมาย
สำหรับตัวอย่างนี้สมมติว่าคุณมีนักเรียน 100 คนซึ่ง 70 คนมีตู้เก็บของ คุณมีตู้เก็บของทั้งหมด50 ตู้ซึ่ง 40 ตู้มีนักเรียนอย่างน้อย 1 คนและตู้เก็บของ 10 ตู้ไม่มีนักเรียน
INNER JOINเทียบเท่ากับ " แสดงให้ฉันเห็นว่านักเรียนทุกคนมีตู้เก็บของ "
นักเรียนที่ไม่มีตู้เก็บของหรือตู้เก็บของที่ไม่มีนักเรียนหายไป
ส่งคืน 70 แถว
ซ้ายนอกเข้าร่วมจะ " แสดงให้ฉันเห็นนักเรียนทุกคนด้วยตู้เก็บของที่สอดคล้องกันถ้าพวกเขามีหนึ่ง "
นี่อาจเป็นรายชื่อนักเรียนทั่วไปหรืออาจใช้เพื่อระบุนักเรียนที่ไม่มีตู้เก็บของ
ส่งคืน 100 แถว
เข้าร่วมด้านขวาจะ " แสดงตู้เก็บของทั้งหมดและนักเรียนที่ได้รับมอบหมายถ้ามี "
สิ่งนี้สามารถใช้เพื่อระบุตู้เก็บของที่ไม่มีนักเรียนที่ได้รับมอบหมายหรือตู้เก็บของที่มีนักเรียนมากเกินไป
ส่งคืน 80 แถว (รายชื่อนักเรียน 70 คนในตู้เก็บของ 40 ตู้พร้อมตู้เก็บของ 10 ตู้ที่ไม่มีนักเรียน)
การเข้าร่วมด้านนอกเต็มรูปแบบจะไร้สาระและอาจไม่ได้ใช้งานมากนัก
บางอย่างเช่น " แสดงให้ฉันเห็นนักเรียนทุกคนและตู้เก็บของทั้งหมดและตรงกับพวกเขาในที่ที่คุณสามารถ "
ส่งคืน 110 แถว (นักเรียนทั้งหมด 100 คนรวมถึงนักเรียนที่ไม่มีตู้เก็บของรวมทั้งตู้เก็บของ 10 ตู้ที่ไม่มีนักเรียน)
ข้ามเข้าร่วมก็ค่อนข้างโง่ในสถานการณ์นี้
มันไม่ได้ใช้lockernumber
ฟิลด์ที่เชื่อมโยงในตารางนักเรียนดังนั้นโดยพื้นฐานแล้วคุณจะได้รายชื่อยักษ์ใหญ่ของการจับคู่แบบจับคู่ระหว่างนักเรียนกับล็อกเกอร์ที่เป็นไปได้ไม่ว่าจะมีอยู่จริงหรือไม่ก็ตาม
ส่งคืน 5,000 แถว (100 นักเรียน x ตู้เก็บของ 50) อาจเป็นประโยชน์ (ที่มีการกรอง) เป็นจุดเริ่มต้นเพื่อจับคู่นักเรียนใหม่กับตู้เก็บที่ว่างเปล่า
SELECT * FROM students RIGHT OUTER JOIN lockers...
SELECT * FROM lockers RIGHT OUTER JOIN students...
คำตอบที่ดี แต่ชอบที่จะเห็นมันอัปเดตด้วยSQL
คำค้นหาที่สมบูรณ์
การเข้าร่วมมีสามประเภท:
INNER
เข้าร่วมเปรียบเทียบสองตารางและส่งกลับผลลัพธ์เฉพาะการแข่งขันที่มีอยู่ ระเบียนจากตารางที่ 1 จะทำซ้ำเมื่อตรงกับผลลัพธ์หลายรายการในอันดับที่ 2 การเข้าร่วมภายในมีแนวโน้มที่จะทำให้ชุดผลลัพธ์มีขนาดเล็กลง แต่เนื่องจากการบันทึกสามารถทำซ้ำได้จึงไม่รับประกันCROSS
เข้าร่วมเปรียบเทียบสองตารางและกลับมารวมกันเป็นไปได้ของแถวจากทั้งสองตาราง คุณสามารถได้รับผลลัพธ์จำนวนมากจากการเข้าร่วมประเภทนี้ที่อาจไม่มีความหมายดังนั้นควรใช้ด้วยความระมัดระวังOUTER
เข้าร่วมเปรียบเทียบสองตารางและส่งกลับข้อมูลเมื่อมีการแข่งขันหรือค่า NULL เช่นเดียวกับการเข้าร่วมของ INNER การทำเช่นนี้จะทำซ้ำแถวในตารางหนึ่งเมื่อตรงกับหลายระเบียนในตารางอื่น ตัวเชื่อมภายนอกมีแนวโน้มที่จะทำให้ชุดผลลัพธ์มีขนาดใหญ่ขึ้นเนื่องจากพวกเขาจะไม่ลบระเบียนใด ๆ ออกจากชุดด้วยตนเอง คุณต้องมีคุณสมบัติเข้าร่วม OUTER เพื่อกำหนดเวลาและสถานที่ที่จะเพิ่มค่า NULL:
LEFT
หมายถึงเก็บระเบียนทั้งหมดจากตารางที่ 1 ไม่ว่าอะไรและแทรกค่า NULL เมื่อตารางที่ 2 ไม่ตรงกัน RIGHT
หมายถึงสิ่งที่ตรงกันข้าม: เก็บบันทึกทั้งหมดจากตารางที่ 2 ไม่ว่าอะไรและแทรกค่า NULL เมื่อเขาตารางที่ 1 ไม่ตรงกัน FULL
หมายถึงเก็บระเบียนทั้งหมดจากทั้งสองตารางและแทรกค่า NULL ในตารางใดก็ได้หากไม่มีการจับคู่บ่อยครั้งที่คุณเห็นว่าOUTER
คำหลักจะถูกตัดออกจากไวยากรณ์ แต่จะเป็นเพียง "LEFT JOIN", "RIGHT JOIN" หรือ "FULL JOIN" สิ่งนี้ทำได้เนื่องจากการเข้าร่วมภายในและ CROSS นั้นไม่มีความหมายใด ๆ เกี่ยวกับซ้ายขวาหรือเต็มดังนั้นสิ่งเหล่านี้เพียงพอสำหรับตัวเองที่จะบ่งบอกว่าการเข้าร่วม OUTER นั้นไม่น่าสงสัยเลย
นี่คือตัวอย่างของเวลาที่คุณอาจต้องการใช้แต่ละประเภท:
INNER
: คุณต้องการส่งคืนระเบียนทั้งหมดจากตาราง "ใบแจ้งหนี้" พร้อมกับ "ใบแจ้งหนี้" ที่เกี่ยวข้อง สมมติว่าใบแจ้งหนี้ที่ถูกต้องทุกใบจะมีอย่างน้อยหนึ่งบรรทัดOUTER
: คุณต้องการส่งคืนระเบียน "InvoiceLines" ทั้งหมดสำหรับใบแจ้งหนี้เฉพาะพร้อมด้วยระเบียน "InventoryItem" ที่เกี่ยวข้อง นี่เป็นธุรกิจที่ขายบริการเช่นกันที่ InvoiceLines ทั้งหมดจะมี IventoryItemCROSS
: คุณมีตารางตัวเลขที่มี 10 แถวแต่ละค่าที่เก็บไว้คือ '0' ถึง '9' คุณต้องการสร้างตารางช่วงวันที่เพื่อเข้าร่วมเพื่อให้คุณได้รับหนึ่งระเบียนสำหรับแต่ละวันภายในช่วง ด้วยการเข้าร่วม CROSS ตารางนี้กับตัวเองซ้ำ ๆ คุณสามารถสร้างจำนวนเต็มต่อเนื่องได้มากเท่าที่คุณต้องการ (เมื่อคุณเริ่มต้นที่ 10 ต่อ 1 พลังงานแต่ละการรวมจะเพิ่ม 1 ไปยังเลขชี้กำลัง) จากนั้นใช้ฟังก์ชัน DATEADD () เพื่อเพิ่มค่าเหล่านั้นในวันที่ฐานของคุณสำหรับช่วงมีเพียง 4 ชนิด:
NULL
สำหรับแต่ละแถวค่าในตารางด้านขวา ซึ่งหมายความว่าทุกแถวจากตารางด้านซ้ายจะปรากฏอย่างน้อยหนึ่งครั้งในผลลัพธ์ "การรวมข้าม" หรือ "การรวมคาร์ทีเซียน" เป็นเพียงการรวมภายในที่ไม่ได้ระบุเงื่อนไขการเข้าร่วมทำให้มีการส่งออกแถวคู่ทั้งหมด
ขอบคุณ RusselH ที่ชี้ให้เห็นว่าการเข้าร่วมเต็มรูปแบบซึ่งฉันได้ข้ามไป
SQL JOINS แตกต่าง:
ง่ายมากที่จะจำ:
INNER JOIN
แสดงเฉพาะระเบียนทั่วไปของทั้งสองตาราง
OUTER JOIN
เนื้อหาทั้งหมดของตารางทั้งสองถูกรวมเข้าด้วยกันไม่ว่าจะตรงกันหรือไม่ก็ตาม
LEFT JOIN
เหมือนกับLEFT OUTER JOIN
- (เลือกระเบียนจากตารางแรก (ซ้ายสุด) ที่มีระเบียนตารางที่ตรงกันที่ตรงกัน)
RIGHT JOIN
เหมือนกับRIGHT OUTER JOIN
- (เลือกระเบียนจากตารางที่สอง (ขวาสุด) ที่มีระเบียนตรงกันกับตารางด้านซ้าย)
ตรวจสอบการเข้าร่วม (SQL) บน Wikipedia
การเข้าร่วมด้านซ้าย / ขวา (ด้านนอก) - ให้สองตารางคืนแถวทั้งหมดที่มีอยู่ในตารางด้านซ้ายหรือขวาของการเข้าร่วมของคุณรวมทั้งแถวจากอีกด้านหนึ่งจะถูกส่งกลับเมื่อเข้าร่วมประโยคเป็นการจับคู่หรือ null จะถูกส่งกลับ คอลัมน์เหล่านั้น
เต็มภายนอก - รับสองตารางส่งคืนแถวทั้งหมดและจะคืนค่า null เมื่อคอลัมน์ด้านซ้ายหรือขวาไม่อยู่ที่นั่น
Cross Joins - การเข้าร่วมคาร์ทีเซียนและอาจเป็นอันตรายหากไม่ได้ใช้อย่างระมัดระวัง
การทำให้มองเห็นได้ชัดเจนขึ้นอาจช่วยได้ ตัวอย่างหนึ่ง:
ตารางที่ 1:
ID_STUDENT STUDENT_NAME
1 Raony
2 Diogo
3 Eduardo
4 Luiz
ตารางที่ 2:
ID_STUDENT LOCKER
3 l1
4 l2
5 l3
สิ่งที่ฉันได้รับเมื่อฉัน:
-Inner join of Table 1 and Table 2:
- Inner join returns both tables merged only when the key
(ID_STUDENT) exists in both tables
ID_STUDENT STUDENT_NAME LOCKER
3 Eduardo l1
4 Luiz l2
-Left join of Table 1 and Table 2:
- Left join merges both tables with all records form table 1, in
other words, there might be non-populated fields from table 2
ID_ESTUDANTE NOME_ESTUDANTE LOCKER
1 Raony -
2 Diogo -
3 Eduardo l1
4 Luiz l2
-Right join of table 1 and table 2:
- Right join merges both tables with all records from table 2, in
other words, there might be non-populated fields from table 1
ID_STUDENT STUDENT_NAME LOCKER
3 Eduardo l1
4 Luiz l2
5 - l3
-Outter join of table 1 and table 2:
- Returns all records from both tables, in other words, there
might be non-populated fields either from table 1 or 2.
ID_STUDENT STUDENT_NAME LOCKER
1 Raony -
2 Diogo -
3 Eduardo l1
4 Luiz l2
5 - l3
Inner join : แสดงเฉพาะแถวเมื่อมีข้อมูลจากทั้งสองตาราง
ด้านนอกเข้าร่วม : (ซ้าย / ขวา) : แสดงผลทั้งหมดจากซ้าย / ขวาตารางที่มีแถวจับคู่ ( s ) ถ้ามันมีอยู่หรือไม่
ตอนแรกคุณต้องเข้าใจว่าการเข้าร่วมทำอะไร เราเชื่อมโยงหลายตารางและรับผลลัพธ์เฉพาะจากตารางที่เข้าร่วม วิธีที่ง่ายที่สุดที่จะทำคือข้ามเข้าร่วม
ให้บอกว่า tableA มีสองคอลัมน์ A และ B และ tableB มีสามคอลัมน์ C และ D หากเราใช้ cross join มันจะสร้างแถวที่ไม่มีความหมายมาก จากนั้นเราต้องจับคู่โดยใช้คีย์หลักเพื่อรับข้อมูลจริง
ซ้าย:มันจะส่งคืนระเบียนทั้งหมดจากตารางด้านซ้ายและระเบียนที่ตรงกันจากตารางด้านขวา
ขวา:มันจะกลับมาตรงกันข้ามกับ Left join มันจะส่งกลับระเบียนทั้งหมดจากตารางด้านขวาและระเบียนที่ตรงกันจากตารางด้านซ้าย
Inner:มันเหมือนกับสี่แยก มันจะส่งกลับเฉพาะระเบียนที่ตรงกันจากทั้งสองตาราง
ด้านนอก:และนี่เป็นเหมือนสหภาพ มันจะส่งคืนระเบียนที่มีอยู่ทั้งหมดจากทั้งสองตาราง
บางครั้งเราไม่ต้องการข้อมูลทั้งหมดและเราควรต้องการข้อมูลหรือบันทึกทั่วไปเท่านั้น เราสามารถรับได้โดยใช้วิธีการเข้าร่วมเหล่านี้ โปรดจำไว้ว่าการเข้าร่วมทางซ้ายและขวาเป็นการเข้าร่วมด้านนอกด้วย
คุณสามารถรับบันทึกทั้งหมดโดยใช้การเข้าร่วมไขว้ แต่มันอาจมีราคาแพงเมื่อพูดถึงบันทึกเป็นล้าน ๆ แผ่น เพื่อให้ง่ายโดยใช้การรวมซ้าย, ขวา, ภายในหรือภายนอก
ขอบคุณ