ความแตกต่างระหว่างการเข้าร่วมซ้ายและขวาเข้าร่วมใน SQL Server


225

ฉันรู้เกี่ยวกับการรวมใน SQL Server

ตัวอย่างเช่น. มีสองตารางคือ Table1, Table2

โครงสร้างตารางของพวกเขามีดังนี้

create table Table1 (id int, Name varchar (10))

create table Table2 (id int, Name varchar (10))

ข้อมูล Table1 ดังต่อไปนี้:

    Id     Name     
    -------------
    1      A        
    2      B    

ข้อมูล Table2 ดังต่อไปนี้:

    Id     Name     
    -------------
    1      A        
    2      B 
    3      C

หากฉันรันทั้งคำสั่ง SQL ที่กล่าวถึงด้านล่างผลลัพธ์ทั้งสองจะเหมือนกัน

select *
from Table1
  left join Table2 on Table1.id = Table2.id

select *
from Table2
  right join Table1 on Table1.id = Table2.id

โปรดอธิบายความแตกต่างระหว่างการเข้าร่วมซ้ายและขวาในคำสั่ง SQL ด้านบน

คำตอบ:


73
Select * from Table1 left join Table2 ...

และ

Select * from Table2 right join Table1 ...

แน่นอนแทนกันอย่างสมบูรณ์ ลองใช้Table2 left join Table1(หรือคู่ที่เหมือนกันTable1 right join Table2) เพื่อดูความแตกต่าง แบบสอบถามนี้ควรให้แถวเพิ่มเติมแก่คุณเนื่องจาก Table2 มีแถวที่มีรหัสซึ่งไม่มีอยู่ในตารางที่ 1


17
เหตุใดเราจึงต้องการRIGHT JOINถ้าเราสามารถบรรลุผลลัพธ์ที่ต้องการด้วยเพียงLEFT JOIN? : P
user1857492

1
@SilapAliyev จริง ๆ แล้วเป็นคำถามที่ดีมาก ใครตอบได้บ้าง : D
Ian Chu Te

21
Select * from Table1 left join Table 2จะส่งคืนระเบียนทั้งหมดของตารางที่ 1 บวกระเบียนที่ตรงกันของตารางที่ 2 ตรงกันข้ามSelect * from Table1 right join Table 2จะส่งกลับระเบียนทั้งหมดจากตารางที่ 2 และระเบียนที่เกี่ยวข้องกันของตารางที่ 1 ความหวังที่จะช่วย
Programador Adagal

3
หากคุณใช้มากกว่า 2 ตารางการใช้การเข้าร่วมทางขวาอาจมีความหมายและอ่านง่าย
ʞɔıɥʇɹɐʞouɐɯ

1
@MarkusMeskanen คุณกำลังเปลี่ยนประโยคง่ายๆ 7 คำ เมื่อคุณมีประโยค 356 บรรทัดที่มีหลาย subsentences และจำเป็นต้องเปลี่ยนตรรกะของ Left Right คุณจะสงสัยว่ามันจะเปลี่ยนเป็น oneword เท่านั้น ...
Programador Adagal

1014

Codeproject มีภาพนี้ซึ่งอธิบายพื้นฐานเบื้องต้นของ SQL joins ซึ่งนำมาจาก: http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx SQL เข้าร่วมอธิบาย


64
ในนั้นมี 'รายละเอียด' ไม่มากนัก เครดิตควรไปที่หน้าโปรแกรมรหัสแทนฉัน แต่แน่นอนว่าฉันไม่สนใจความสนใจ :-)
Daan Timmer

6
@Daan Timmer ไม่ต้องมีเครดิตกับคุณด้วย! คุณบรรจุหีบห่อใหม่และขายต่อตามความต้องการเฉพาะและเฉพาะเจาะจง ผู้ค้าปลีกทำเช่นเดียวกันและรับ $$ พันล้าน
BKSpurgeon

ฉันรู้สึกว่าเราอาจจำเป็นต้องมีเงื่อนไข "และ" ในกรณีที่ประโยคสุดท้ายของ "การรวมภายนอกไม่รวม" ฉันรู้สึกว่าจำเป็นต้องอัปเดตการค้นหาเป็น SELECT <select_list> จาก Table_A เข้าร่วมเต็มตาราง Table_B B บน A.Key = B.Key ที่ A.Key ไหน NULL และ B.Key IS NULL
vinsinraw

@ vinsinraw ที่ไม่จำเป็น เพราะนั่นครอบคลุมอยู่ในเงื่อนไขแล้ว: JOIN Table_B b ON A.Key = B.Key. สภาพ OR ทำงานได้ดี
Daan Timmer

นี่คือการละเมิดทั่วไปของ Venn diagrams แวดวง A & B ไม่ได้แสดงถึงตาราง A & B, วงกลม A คือ A ซ้ายเข้าร่วม B & cirlce B คือ A RIGHT JOIN B นอกจากนี้ยังไม่สำคัญว่าเงื่อนไข ON คือ & ปุ่มไม่เกี่ยวข้องและไม่ทำงาน กรณี. ดูความคิดเห็นและคำตอบของฉันในหน้านี้และส่วนนี้แผนภาพเวนน์เรื่อง
philipxy

37

ตารางที่คุณกำลังรับข้อมูลคือ 'ซ้าย'
ตารางที่คุณเข้าร่วมคือ 'RIGHT'
ซ้ายเข้าร่วม: นำรายการทั้งหมดจากตารางด้านซ้ายและ (เฉพาะ) รายการที่ตรงกันจากตารางด้านขวา
เข้าร่วมทันที: นำรายการทั้งหมดจากตารางด้านขวาและ (เฉพาะ) รายการที่ตรงกันจากตารางด้านซ้าย
ดังนั้น:

Select * from Table1 left join Table2 on Table1.id = Table2.id  

ให้:

Id     Name       
-------------  
1      A          
2      B      

แต่:

Select * from Table1 right join Table2 on Table1.id = Table2.id

ให้:

Id     Name       
-------------  
1      A          
2      B   
3      C  

คุณมีสิทธิ์เข้าร่วมตารางที่มีจำนวนแถวน้อยลงในตารางที่มีจำนวนแถวมากขึ้น
และ
อีกครั้งให้ออกจากตารางเข้าร่วมที่มีจำนวนแถวน้อยลงในตารางที่มีจำนวนแถวมากขึ้น
ลอง:

 If Table1.Rows.Count > Table2.Rows.Count Then  
    ' Left Join  
 Else  
    ' Right Join  
 End If  

22

(ภายใน) เข้าร่วม:ส่งกลับระเบียนที่มีค่าที่ตรงกันในตารางทั้งสอง

ซ้าย (ด้านนอก) เข้าร่วม:คืนระเบียนทั้งหมดจากตารางด้านซ้ายและระเบียนที่ตรงกันจากตารางด้านขวา

RIGHT (OUTER) JOIN:ส่งคืนระเบียนทั้งหมดจากตารางด้านขวาและระเบียนที่ตรงกันจากตารางด้านซ้าย

เข้าร่วมเต็มรูปแบบ (ออกด้านนอก):ส่งคืนระเบียนทั้งหมดเมื่อมีการแข่งขันในตารางด้านซ้ายหรือด้านขวา

ตัวอย่างเช่นสมมติว่าเรามีสองตารางที่มีระเบียนต่อไปนี้:

ตารางที่

id   firstname   lastname
___________________________
1     Ram         Thapa
2     sam         Koirala
3     abc         xyz
6    sruthy       abc

ตาราง B

id2   place
_____________
1      Nepal
2      USA
3      Lumbini
5      Kathmandu

เข้าร่วม Inner

หมายเหตุ: มันให้จุดตัดของสองตาราง

เข้าร่วม Inner

วากยสัมพันธ์

SELECT column_name FROM table1 INNER JOIN table2 ON table1.column_name = table2.column_name;

นำไปใช้ในตารางตัวอย่างของคุณ:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA INNER JOIN TableB ON TableA.id = TableB.id2;

ผลลัพธ์จะเป็น:

firstName       lastName       Place
_____________________________________
  Ram         Thapa             Nepal
  sam         Koirala            USA
  abc         xyz              Lumbini

เข้าร่วมซ้าย

หมายเหตุ: จะให้แถวที่เลือกทั้งหมดใน TableA รวมถึงแถวที่เลือกทั่วไปใน TableB

เข้าร่วมซ้าย

SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name = table2.column_name;

นำไปใช้ในตารางตัวอย่างของคุณ

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA LEFT JOIN TableB ON TableA.id = TableB.id2;

ผลลัพธ์จะเป็น:

firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        Null

เข้าร่วมขวา

หมายเหตุ: จะให้แถวที่เลือกทั้งหมดใน TableB รวมถึงแถวที่เลือกทั่วไปใน TableA

เข้าร่วมขวา

ไวยากรณ์:

SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column_name = table2.column_name;

นำไปใช้ในตาราง samole ของคุณ:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA RIGHT JOIN TableB ON TableA.id = TableB.id2;

ผลลัพธ์จะ bw:

firstName   lastName     Place
______________________________
Ram         Thapa         Nepal
sam         Koirala       USA
abc         xyz           Lumbini
Null        Null          Kathmandu

เข้าร่วมเต็ม

หมายเหตุ: มันเหมือนกับการดำเนินการสหภาพมันจะคืนค่าที่เลือกทั้งหมดจากทั้งสองตาราง

เข้าร่วมเต็ม

ไวยากรณ์:

SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.column_name = table2.column_name;

ใช้ใน samp ของคุณ [le table:

SELECT TableA.firstName,TableA.lastName,TableB.Place FROM TableA FULL JOIN TableB ON TableA.id = TableB.id2;

ผลลัพธ์จะเป็น:

firstName   lastName    Place
______________________________
 Ram         Thapa      Nepal
 sam         Koirala    USA
 abc         xyz        Lumbini
sruthy       abc        Null
 Null         Null      Kathmandu

ข้อเท็จจริงบางอย่าง

สำหรับ INNER เข้าร่วมการสั่งซื้อไม่สำคัญ

สำหรับ OUTER (ซ้ายขวาหรือเต็ม) การรวมเข้าด้วยกัน

ค้นหาเพิ่มเติมได้ที่w3schools


12
select fields 
from tableA --left
left join tableB --right
on tableA.key = tableB.key

ตารางในfromตัวอย่างtableAนี้อยู่ทางด้านซ้ายของความสัมพันธ์

tableA <- tableB
[left]------[right]

ดังนั้นหากคุณต้องการที่จะนำแถวทั้งหมดออกจากตารางด้านซ้าย ( tableA) แม้ว่าจะไม่มีรายการที่ตรงกันในตารางด้านขวา ( tableB) คุณจะต้องใช้ "การเข้าร่วมด้านซ้าย"

และถ้าคุณต้องการที่จะนำแถวทั้งหมดจากตารางด้านขวา ( tableB) แม้ว่าจะไม่มีการจับคู่ในตารางด้านซ้าย ( tableA) คุณจะใช้right joinคุณจะใช้

ดังนั้นแบบสอบถามต่อไปนี้เทียบเท่ากับที่ใช้ข้างต้น

select fields
from tableB 
right join tableA on tableB.key = tableA.key

10

คุณดูเหมือนจะถามว่า "ถ้าฉันสามารถเขียนไวยากรณ์ที่RIGHT OUTER JOINใช้LEFT OUTER JOINแล้วทำไมมีRIGHT OUTER JOINไวยากรณ์เลย" ฉันคิดว่าคำตอบสำหรับคำถามนี้คือเนื่องจากผู้ออกแบบภาษาไม่ต้องการ จำกัด ผู้ใช้ (และฉันคิดว่าพวกเขาจะถูกวิจารณ์ถ้าพวกเขาทำ) ซึ่งจะบังคับให้ผู้ใช้เปลี่ยนลำดับของตาราง ในFROMข้อในบางสถานการณ์เมื่อเพียงเปลี่ยนประเภทการรวม


บางครั้งการรวมด้านนอกซ้ายและขวาสามารถใช้แทนกันได้ทั้งหมดถูกต้องหรือไม่
アレックス

4
@Alex: การรวมภายนอกด้านซ้ายและขวาแน่นอนสามารถใช้แทนกันได้เสมอ
onedaywhen

8

ข้อความทั้งสองของคุณเทียบเท่ากัน

คนส่วนใหญ่ใช้งานได้เพียงLEFT JOINเพราะดูเหมือนว่าใช้งานง่ายกว่าและเป็นไวยากรณ์สากล - ฉันไม่คิดว่า RDBMS รองรับRIGHT JOINทั้งหมด


"ฉันไม่คิดว่า RDBMS ทั้งหมดรองรับ RIGHT JOIN" - แน่นอนไม่ใช่ RDBMS ทั้งหมดสนับสนุน SQL แต่ถ้าคุณหมายถึงว่าผลิตภัณฑ์ SQL บางตัวสนับสนุนLEFTแต่ไม่ใช่RIGHTโปรดระบุว่าผลิตภัณฑ์ชนิดใด
oneday เมื่อ

10
@onedaywhen ตัวอย่างเช่น SQLite 3 ไม่ได้ใช้งานRIGHTและFULL OUTER JOIN : sqlite.org/omitted.html
Mac_Cain13

0

ผมรู้สึกว่าเราอาจจำเป็นต้องมีANDเงื่อนไขในwhereข้อของตัวเลขสุดท้ายของเพื่อที่เราจะได้รับผลที่ต้องการของOuter Excluding JOIN A Union B Minus A Interaction Bฉันรู้สึกว่าจำเป็นต้องได้รับการอัปเดตเป็น

SELECT <select_list>
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.Key = B.Key
WHERE A.Key IS NULL AND B.Key IS NULL

ถ้าเราใช้ORแล้วเราจะได้ผลลัพธ์ทั้งหมดของA Union B


0

เลือก * จาก Table1 ซ้ายเข้าร่วม Table2 บน Table1.id = Table2.id

ในแบบสอบถามแรกซ้ายเข้าร่วมเปรียบเทียบตารางด้านซ้ายtable1กับตารางด้านขวาtable2 table2

ในคุณสมบัติทั้งหมดของtable1 ที่จะแสดงในขณะที่ในtable2เฉพาะคุณสมบัติเหล่านั้นที่จะแสดงในสภาพที่ได้รับจริง

เลือก * จาก Table2 เข้าร่วม Table1 บน Table1.id = Table2.id

ในแบบสอบถามแรกขวาเข้าร่วมเปรียบเทียบด้านขวาตารางtable1ไปซ้ายด้านตารางtable2

ในคุณสมบัติทั้งหมดของtable1 ที่จะแสดงในขณะที่ในtable2เฉพาะคุณสมบัติเหล่านั้นที่จะแสดงในสภาพที่ได้รับจริง

แบบสอบถามทั้งสองจะให้ผลลัพธ์เดียวกันเนื่องจากลำดับของการประกาศตารางในแบบสอบถามแตกต่างกันเช่นคุณกำลังประกาศtable1และtable2ในซ้ายและขวาตามลำดับในแบบสอบถามการรวมซ้ายแรกและยังประกาศtable1และtable2ในขวาและซ้ายตามลำดับในการเข้าร่วมที่สองขวาสอบถาม

นี่คือเหตุผลที่คุณได้ผลลัพธ์เหมือนกันทั้งสองข้อความค้นหา ดังนั้นหากคุณต้องการผลลัพธ์ที่แตกต่างจากนั้นเรียกใช้แบบสอบถามทั้งสองนี้ตามลำดับ

เลือก * จาก Table1 ซ้ายเข้าร่วม Table2 บน Table1.id = Table2.id

เลือก * จาก Table1 ด้านขวาเข้าร่วม Table2 บน Table1.id = Table2.id


0

Select * from Table1 t1 Left Join Table2 t2 on t1.id=t2.id ตามคำจำกัดความ: การเข้าร่วมด้านซ้ายเลือกคอลัมน์ทั้งหมดที่กล่าวถึงด้วยคำหลัก "เลือก" จากตารางที่ 1 และคอลัมน์จากตารางที่ 2 ซึ่งตรงกับเกณฑ์หลังจากคำหลัก "บน"

ในทำนองเดียวกันโดยนิยาม: เข้าร่วมขวาเลือกคอลัมน์ทั้งหมดที่กล่าวถึงด้วยคำหลัก "เลือก" จากตารางที่ 2 และคอลัมน์จากตารางที่ 1 ซึ่งตรงกับเกณฑ์หลังจากคำหลัก "ใน"

อ้างอิงถึงคำถามของคุณ id ในทั้งสองตารางจะถูกนำมาเปรียบเทียบกับคอลัมน์ทั้งหมดที่จำเป็นในการส่งออก ดังนั้นรหัส 1 และ 2 จึงเป็นเรื่องธรรมดาในทั้งตารางและเป็นผลให้คุณมีสี่คอลัมน์ที่มีidและคอลัมน์ชื่อจากตารางแรกและตารางที่สองตามลำดับ

*select * from Table1 left join Table2 on Table1.id = Table2.id

นิพจน์ด้านบนจะใช้ระเบียนทั้งหมด (แถว) จากตารางที่ 1 และคอลัมน์โดยมีid ที่ตรงกันจากตารางที่ 1 และตารางที่ 2 จากตารางที่ 2

select * from Table2 right join Table1 on Table1.id = Table2.id**

ในทำนองเดียวกันจากนิพจน์ด้านบนจะใช้ระเบียนทั้งหมด (แถว) จากตารางที่ 1 และคอลัมน์ที่มีid ที่ตรงกันจากตารางที่ 1 และตารางที่ 2 จากตารางที่ 2 (จำไว้ว่านี่เป็นการเข้าร่วมที่ถูกต้องดังนั้นคอลัมน์ทั้งหมดจากตารางที่ 2 จาก table1 จะได้รับการพิจารณา)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.