ฉันต้องการเข้าร่วมเต็มรูปแบบใน MySQL เป็นไปได้ไหม เต็มภายนอกเข้าร่วมสนับสนุนโดย MySQL หรือไม่
ฉันต้องการเข้าร่วมเต็มรูปแบบใน MySQL เป็นไปได้ไหม เต็มภายนอกเข้าร่วมสนับสนุนโดย MySQL หรือไม่
คำตอบ:
คุณไม่มีการเข้าร่วมเต็มรูปแบบบน MySQL แต่คุณสามารถเลียนแบบพวกเขาได้
สำหรับรหัสตัวอย่างที่ถอดความจากคำถาม SO นี้คุณมี:
ด้วยสองตาราง t1, t2:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
แบบสอบถามด้านบนใช้สำหรับกรณีพิเศษที่การดำเนินการ JOIN FULL OUTER JOIN จะไม่สร้างแถวที่ซ้ำกัน แบบสอบถามด้านบนขึ้นอยู่กับตัวUNION
ดำเนินการตั้งค่าเพื่อลบแถวที่ซ้ำกันที่แนะนำโดยรูปแบบแบบสอบถาม เราสามารถหลีกเลี่ยงการแนะนำแถวที่ซ้ำกันโดยใช้รูปแบบการต่อต้านการเข้าร่วมสำหรับการสืบค้นที่สองจากนั้นใช้ตัวดำเนินการชุด UNION ALL เพื่อรวมสองชุดเข้าด้วยกัน ในกรณีทั่วไปมากขึ้นที่การรวมเอาเต็มจะกลับแถวที่ซ้ำกันเราสามารถทำได้:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION ALL
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.id IS NULL
(SELECT ... FROM tbl1 LEFT JOIN tbl2 ...) UNION ALL (SELECT ... FROM tbl1 RIGHT JOIN tbl2 ... WHERE tbl1.col IS NULL)
t1
และt2
แบบสอบถามในคำตอบนี้จะส่งกลับ resultset ที่เลียนแบบ FULL OUTER JOIN แต่ในกรณีทั่วไปมากขึ้นตัวอย่างเช่นรายการ SELECT ไม่ได้มีคอลัมน์เพียงพอ / นิพจน์ที่จะทำให้แถวกลับไม่ซ้ำกันแล้วรูปแบบแบบสอบถามนี้ไม่เพียงพอFULL OUTER JOIN
ที่จะทำให้เกิดการตั้งค่าที่จะได้รับการผลิตโดย เพื่อให้ได้การจำลองที่ซื่อสัตย์ยิ่งขึ้นเราต้องการตัวUNION ALL
ดำเนินการชุดหนึ่งและหนึ่งในแบบสอบถามจะต้องมีรูปแบบการต่อต้านการเข้าร่วม ความคิดเห็นจากPavle Lekic (ด้านบน) ให้รูปแบบแบบสอบถามที่ถูกต้อง
คำตอบที่Pablo Santa Cruzให้นั้นถูกต้อง อย่างไรก็ตามในกรณีที่ใครก็ตามที่เข้ามาในหน้านี้และต้องการคำชี้แจงเพิ่มเติมนี่คือรายละเอียด
สมมติว่าเรามีตารางต่อไปนี้:
-- t1
id name
1 Tim
2 Marta
-- t2
id name
1 Tim
3 Katarina
การเข้าร่วมภายในเช่นนี้:
SELECT *
FROM `t1`
INNER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
จะให้เรามีเพียงระเบียนที่ปรากฏในตารางทั้งสองแบบนี้:
1 Tim 1 Tim
การรวมภายในไม่มีทิศทาง (เช่นซ้ายหรือขวา) เนื่องจากมีทิศทางสองทิศทางอย่างชัดเจน - เราต้องการการแข่งขันทั้งสองด้าน
ในทางกลับกันการรวมภายนอกนั้นใช้สำหรับค้นหาระเบียนที่อาจไม่มีการแข่งขันในตารางอื่น ดังนั้นคุณต้องระบุที่ด้านข้างของเข้าร่วมได้รับอนุญาตให้มีการบันทึกที่ขาดหายไป
LEFT JOIN
และRIGHT JOIN
จดชวเลขLEFT OUTER JOIN
และRIGHT OUTER JOIN
; ฉันจะใช้ชื่อเต็มของพวกเขาด้านล่างเพื่อเสริมแนวคิดของการรวมภายนอกกับการรวมภายใน
การเข้าร่วมด้านนอกด้านซ้ายเช่นนี้:
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
... จะให้เราทุกระเบียนจากตารางด้านซ้ายโดยไม่คำนึงว่าพวกเขามีการแข่งขันในตารางด้านขวาเช่นนี้:
1 Tim 1 Tim
2 Marta NULL NULL
การเข้าร่วมภายนอกที่ถูกต้องเช่นนี้:
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
... จะให้เราทุกระเบียนจากตารางด้านขวาโดยไม่คำนึงว่าพวกเขามีการแข่งขันในตารางด้านซ้ายเช่นนี้
1 Tim 1 Tim
NULL NULL 3 Katarina
การเข้าร่วมรอบนอกเต็มรูปแบบจะให้ระเบียนทั้งหมดจากทั้งสองตารางไม่ว่าจะมีการแข่งขันในตารางอื่นหรือไม่โดยมี NULL ทั้งสองด้านที่ไม่มีการแข่งขัน ผลลัพธ์จะเป็นดังนี้:
1 Tim 1 Tim
2 Marta NULL NULL
NULL NULL 3 Katarina
อย่างไรก็ตามตามที่ Pablo Santa Cruz ชี้ให้เห็นว่า MySQL ไม่รองรับสิ่งนี้ เราสามารถเลียนแบบได้ด้วยการเข้าร่วม UNION จากซ้ายเข้าร่วมและเข้าร่วมขวาเช่นนี้
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
คุณสามารถคิดถึงUNION
ความหมายเป็น "เรียกใช้แบบสอบถามทั้งสองนี้แล้วซ้อนผลลัพธ์ที่ด้านบนของกันและกัน"; แถวบางแถวจะมาจากคิวรีแรกและบางแถวจากแถวที่สอง
ควรสังเกตว่าUNION
ใน MySQL จะกำจัดรายการที่ซ้ำกัน: Tim จะปรากฏในทั้งสองแบบสอบถามที่นี่ แต่ผลลัพธ์ของUNION
รายการเดียวเขาครั้งเดียว เพื่อนร่วมงานกูรูฐานข้อมูลของฉันรู้สึกว่าพฤติกรรมนี้ไม่ควรเชื่อถือ เพื่อให้ชัดเจนยิ่งขึ้นเกี่ยวกับเรื่องนี้เราสามารถเพิ่มส่วนWHERE
คำสั่งในแบบสอบถามที่สอง:
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
WHERE `t1`.`id` IS NULL;
ในทางกลับกันถ้าคุณต้องการUNION ALL
ที่จะเห็นรายการที่ซ้ำกันด้วยเหตุผลบางอย่างที่คุณสามารถใช้
FULL OUTER JOIN
ที่จะไม่ได้รับการผลิตโดย ไม่มีอะไรผิดปกติในการทำแบบสอบถามด้วยวิธีนี้และใช้ UNION เพื่อลบรายการที่ซ้ำกัน แต่เพื่อทำซ้ำ a จริง ๆFULL OUTER JOIN
เราต้องการหนึ่งในแบบสอบถามเพื่อต่อต้านการเข้าร่วม
UNION
ดำเนินการจะลบข้อมูลที่ซ้ำกันออกไป แต่มันยังลบแถวที่ซ้ำกันทั้งหมดรวมถึงแถวที่ซ้ำกันซึ่งจะอยู่ในคืนโดย FULL OUTER JOIN ที่จะเลียนแบบรูปแบบที่ถูกต้องคือa FULL JOIN b
(a LEFT JOIN b) UNION ALL (b ANTI JOIN a)
การใช้union
คิวรีจะเป็นการลบรายการที่ซ้ำกันและสิ่งนี้แตกต่างจากพฤติกรรมfull outer join
ที่ไม่เคยลบสิ่งที่ซ้ำกัน:
[Table: t1] [Table: t2]
value value
------- -------
1 1
2 2
4 2
4 5
นี่คือผลลัพธ์ที่คาดหวังของfull outer join
:
value | value
------+-------
1 | 1
2 | 2
2 | 2
Null | 5
4 | Null
4 | Null
นี่คือผลลัพธ์ของการใช้left
และright Join
ด้วยunion
:
value | value
------+-------
Null | 5
1 | 1
2 | 2
4 | Null
ข้อความค้นหาที่แนะนำของฉันคือ:
select
t1.value, t2.value
from t1
left outer join t2
on t1.value = t2.value
union all -- Using `union all` instead of `union`
select
t1.value, t2.value
from t2
left outer join t1
on t1.value = t2.value
where
t1.value IS NULL
ผลลัพธ์ของข้อความค้นหาข้างต้นที่เหมือนกับผลลัพธ์ที่คาดไว้:
value | value
------+-------
1 | 1
2 | 2
2 | 2
4 | NULL
4 | NULL
NULL | 5
@ Steve Chambers : [จากการแสดงความคิดเห็นด้วยขอบคุณมาก!]
หมายเหตุ:FULL OUTER JOIN
นี่อาจจะเป็นทางออกที่ดีที่สุดทั้งสำหรับประสิทธิภาพและการสร้างผลเช่นเดียวกับ โพสต์บล็อกนี้ยังอธิบายได้เป็นอย่างดี - อ้างจากวิธีที่ 2: "นี่จัดการแถวที่ซ้ำกันอย่างถูกต้องและไม่รวมสิ่งใด ๆ ที่มันไม่ควรจำเป็นต้องใช้UNION ALL
แทนธรรมดาUNION
ซึ่งจะกำจัดสิ่งที่ซ้ำกันที่ฉันต้องการเก็บไว้ อาจมีประสิทธิภาพมากขึ้นในชุดผลลัพธ์ขนาดใหญ่เนื่องจากไม่จำเป็นต้องเรียงลำดับและลบรายการซ้ำ "
ฉันตัดสินใจเพิ่มโซลูชันอื่นที่มาจากการfull outer join
สร้างภาพและคณิตศาสตร์มันไม่ได้ดีไปกว่านั้น แต่อ่านได้มากขึ้น:
การเข้าร่วมภายนอกเต็มรูปแบบหมายถึง
(t1 ∪ t2)
: ทั้งหมดในt1
หรือในt2
(t1 ∪ t2) = (t1 ∩ t2) + t1_only + t2_only
: ทั้งหมดในทั้งt1
และt2
รวมทั้งหมดในt1
ที่ไม่ได้อยู่ในt2
และบวกทั้งหมดในt2
ที่ไม่ได้อยู่ในt1
:
-- (t1 ∩ t2): all in both t1 and t2
select t1.value, t2.value
from t1 join t2 on t1.value = t2.value
union all -- And plus
-- all in t1 that not exists in t2
select t1.value, null
from t1
where not exists( select 1 from t2 where t2.value = t1.value)
union all -- and plus
-- all in t2 that not exists in t1
select null, t2.value
from t2
where not exists( select 1 from t1 where t2.value = t1.value)
FULL OUTER JOIN
วิธีการนี้น่าจะเป็นทางออกที่ดีที่สุดทั้งสำหรับประสิทธิภาพและการสร้างผลเช่นเดียวกับ โพสต์บล็อกนี้ยังอธิบายได้เป็นอย่างดี - การอ้างอิงจากวิธีที่ 2: "นี่จัดการแถวที่ซ้ำกันอย่างถูกต้องและไม่รวมสิ่งใดที่ไม่ควรใช้ยูเนี่ยนทั้งหมดแทนยูเนี่ยนธรรมดาซึ่งจะกำจัดสิ่งที่ซ้ำกันที่ฉันต้องการ เก็บไว้ซึ่งอาจมีประสิทธิภาพมากขึ้นในชุดผลลัพธ์ขนาดใหญ่เนื่องจากไม่จำเป็นต้องเรียงลำดับและลบรายการที่ซ้ำกัน "
MySql ไม่มีไวยากรณ์ FULL-OUTER-JOIN คุณต้องเลียนแบบโดยทำทั้งซ้ายและขวาเข้าร่วมดังต่อไปนี้ -
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
แต่ MySql ยังไม่มีไวยากรณ์ RIGHT JOIN ตามการทำให้การรวมภายนอกของ MySql ง่ายขึ้นการเข้าร่วมที่เหมาะสมจะถูกแปลงเป็นการเข้าร่วมด้านซ้ายที่เทียบเท่าโดยการสลับ t1 และ t2 ในFROM
และON
clause ในแบบสอบถาม ดังนั้น MySql Query Optimizer แปลแบบสอบถามต้นฉบับเป็นดังต่อไปนี้ -
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t2
LEFT JOIN t1 ON t2.id = t1.id
ตอนนี้ไม่มีอันตรายใด ๆ ในการเขียนแบบสอบถามต้นฉบับตามที่เป็นอยู่ แต่บอกว่าถ้าคุณมีภาคแสดงเช่นคำสั่งย่อย WHERE ซึ่งเป็นภาคก่อนที่จะเข้าร่วมหรือคำกริยาและคำกริยาและON
ประโยคที่อยู่ในระหว่างเข้าร่วมแล้วคุณ อาจต้องการดูปีศาจ ซึ่งอยู่ในรายละเอียด
เครื่องมือเพิ่มประสิทธิภาพคิวรี MySql จะตรวจสอบเพรดิเคตเป็นประจำหากพวกเขาปฏิเสธด้วยค่า null ตอนนี้ถ้าคุณทำ RIGHT JOIN แต่ด้วย WHERE predicate บนคอลัมน์จาก t1 คุณอาจมีความเสี่ยงที่จะพบสถานการณ์ที่ปฏิเสธ
ตัวอย่างเช่นแบบสอบถามต่อไปนี้ -
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'
รับการแปลเป็นภาษาต่อไปนี้โดย Query Optimizer-
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'
UNION
SELECT * FROM t2
LEFT JOIN t1 ON t2.id = t1.id
WHERE t1.col1 = 'someValue'
ดังนั้นลำดับของตารางจึงเปลี่ยนไป แต่เพรดิเคตยังคงใช้กับ t1 แต่ตอนนี้ t1 อยู่ในส่วนคำสั่ง 'ON' หาก t1.col1 ถูกกำหนดให้เป็นNOT NULL
คอลัมน์แล้วแบบสอบถามนี้จะเป็นโมฆะเป็นปฏิเสธ
การเข้าร่วมด้านนอกใด ๆ (ซ้าย, ขวา, เต็ม) ที่ถูกปฏิเสธเป็นโมฆะจะถูกแปลงเป็น MySql ที่เข้าร่วมวงใน
ดังนั้นผลลัพธ์ที่คุณอาจคาดหวังอาจแตกต่างอย่างสิ้นเชิงจากสิ่งที่ MySql ส่งคืน คุณอาจคิดว่ามันเป็นข้อผิดพลาดกับ RIGHT JOIN ของ MySql แต่นั่นไม่ถูกต้อง นี่เป็นเพียงการทำงานของเครื่องมือเพิ่มประสิทธิภาพแบบสอบถาม MySql ดังนั้นผู้พัฒนาที่รับผิดชอบจะต้องใส่ใจกับความแตกต่างเหล่านี้เมื่อเขาสร้างแบบสอบถาม
ใน SQLite คุณควรทำสิ่งนี้:
SELECT *
FROM leftTable lt
LEFT JOIN rightTable rt ON lt.id = rt.lrid
UNION
SELECT lt.*, rl.* -- To match column set
FROM rightTable rt
LEFT JOIN leftTable lt ON lt.id = rt.lrid
ไม่มีคำตอบข้างต้นที่ถูกต้องจริงเพราะพวกเขาไม่ปฏิบัติตามความหมายเมื่อมีค่าซ้ำ
สำหรับแบบสอบถามเช่น (จากรายการที่ซ้ำกันนี้):
SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.Name = t2.Name;
เทียบเท่าที่ถูกต้องคือ:
SELECT t1.*, t2.*
FROM (SELECT name FROM t1 UNION -- This is intentionally UNION to remove duplicates
SELECT name FROM t2
) n LEFT JOIN
t1
ON t1.name = n.name LEFT JOIN
t2
ON t2.name = n.name;
หากคุณต้องการสำหรับการทำงานที่มีNULL
ค่า (ซึ่งก็อาจจะเป็นสิ่งที่จำเป็น) จากนั้นใช้NULL
ตัวดำเนินการเปรียบเทียบ -Safe, มากกว่า<=>
=
FULL OUTER JOIN
เมื่อใดก็ตามที่name
คอลัมน์ไม่มีค่า union all
แบบสอบถามเข้าร่วมต่อต้านรูปแบบควรทำซ้ำเข้าร่วม outer พฤติกรรมอย่างถูกต้อง แต่วิธีการแก้ปัญหาที่มีความเหมาะสมขึ้นอยู่กับบริบทและข้อ จำกัด ที่มีการใช้งานบนโต๊ะ
union all
แต่คำตอบนั้นพลาดรูปแบบการต่อต้านการเข้าร่วมในการสืบค้นครั้งแรกหรือครั้งที่สองที่จะเก็บสำเนาที่มีอยู่เดิม ขึ้นอยู่กับบริบทโซลูชันอื่น ๆ (เช่นนี้) อาจเหมาะสมกว่า
แก้ไขข้อความค้นหา shA.t เพื่อความชัดเจนมากขึ้น:
-- t1 left join t2
SELECT t1.value, t2.value
FROM t1 LEFT JOIN t2 ON t1.value = t2.value
UNION ALL -- include duplicates
-- t1 right exclude join t2 (records found only in t2)
SELECT t1.value, t2.value
FROM t1 RIGHT JOIN t2 ON t1.value = t2.value
WHERE t2.value IS NULL
คุณสามารถทำสิ่งต่อไปนี้:
(SELECT
*
FROM
table1 t1
LEFT JOIN
table2 t2 ON t1.id = t2.id
WHERE
t2.id IS NULL)
UNION ALL
(SELECT
*
FROM
table1 t1
RIGHT JOIN
table2 t2 ON t1.id = t2.id
WHERE
t1.id IS NULL);
คุณจะพูดอะไรเกี่ยวกับCross join solution
SELECT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2
ON 1=1;
select (select count(*) from t1) * (select count(*) from t2))
แถวในชุดผลลัพธ์
SELECT
a.name,
b.title
FROM
author AS a
LEFT JOIN
book AS b
ON a.id = b.author_id
UNION
SELECT
a.name,
b.title
FROM
author AS a
RIGHT JOIN
book AS b
ON a.id = b.author_id
เป็นไปได้เช่นกัน แต่คุณต้องพูดถึงชื่อเขตข้อมูลเดียวกันในการเลือก
SELECT t1.name, t2.name FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT t1.name, t2.name FROM t2
LEFT JOIN t1 ON t1.id = t2.id
ฉันแก้ไขการตอบสนองและผลงานรวมแถวทั้งหมด (ตามการตอบสนองของ Pavle Lekic)
(
SELECT a.* FROM tablea a
LEFT JOIN tableb b ON a.`key` = b.key
WHERE b.`key` is null
)
UNION ALL
(
SELECT a.* FROM tablea a
LEFT JOIN tableb b ON a.`key` = b.key
where a.`key` = b.`key`
)
UNION ALL
(
SELECT b.* FROM tablea a
right JOIN tableb b ON b.`key` = a.key
WHERE a.`key` is null
);
tablea
ที่ไม่มีการแข่งขันในtableb
และในทางกลับกัน คุณลองใช้UNION ALL
ซึ่งจะใช้ได้ก็ต่อเมื่อสองตารางนี้มีคอลัมน์ที่เรียงลำดับเท่ากันซึ่งไม่รับประกัน
ตอบ:
SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;
สามารถสร้างใหม่ได้ดังนี้:
SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
LEFT JOIN t1 ON t1.id = tmp.id
LEFT JOIN t2 ON t2.id = tmp.id;
การใช้คำตอบ UNION หรือ UNION ทั้งหมดไม่ครอบคลุมกรณีขอบซึ่งตารางฐานมีรายการที่ซ้ำกัน
คำอธิบาย:
มีกรณีขอบที่ยูเนี่ยนหรือยูเนี่ยนทั้งหมดไม่สามารถครอบคลุม เราไม่สามารถทดสอบสิ่งนี้บน mysql ได้เนื่องจากมันไม่รองรับ FULL OUTER JOIN แต่เราสามารถแสดงให้เห็นได้ในฐานข้อมูลที่รองรับ:
WITH cte_t1 AS
(
SELECT 1 AS id1
UNION ALL SELECT 2
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 6
),
cte_t2 AS
(
SELECT 3 AS id2
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 6
)
SELECT * FROM cte_t1 t1 FULL OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2;
This gives us this answer:
id1 id2
1 NULL
2 NULL
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
วิธีการแก้ปัญหา UNION:
SELECT * FROM cte_t1 t1 LEFT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
UNION
SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
ให้คำตอบที่ไม่ถูกต้อง:
id1 id2
NULL 3
NULL 4
1 NULL
2 NULL
5 5
6 6
โซลูชัน UNION ALL:
SELECT * FROM cte_t1 t1 LEFT OUTER join cte_t2 t2 ON t1.id1 = t2.id2
UNION ALL
SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
ยังไม่ถูกต้อง
id1 id2
1 NULL
2 NULL
5 5
6 6
6 6
6 6
6 6
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
โดยที่แบบสอบถามนี้:
SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
LEFT JOIN t1 ON t1.id = tmp.id
LEFT JOIN t2 ON t2.id = tmp.id;
ให้สิ่งต่อไปนี้:
id1 id2
1 NULL
2 NULL
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
คำสั่งซื้อนั้นแตกต่างกัน แต่ตรงกับคำตอบที่ถูกต้อง
UNION ALL
วิธีแก้ปัญหา นอกจากนี้ยังนำเสนอโซลูชันที่ใช้UNION
ซึ่งจะช้าลงในตารางแหล่งที่มาขนาดใหญ่เนื่องจากการทำซ้ำที่จำเป็น ในที่สุดก็จะไม่รวบรวมเพราะสนามไม่อยู่ในแบบสอบถามย่อยid
tmp
UNION ALL
แก้ปัญหา: ... ยังไม่ถูกต้อง" รหัสที่คุณใบปัจจุบันออกจากสี่แยกยกเว้นจากขวาเข้าร่วม ( where t1.id1 is null
) UNION ALL
ที่จะต้องมีการระบุไว้ใน กล่าวคือโซลูชันของคุณสำคัญกว่าโซลูชันอื่นทั้งหมดเฉพาะเมื่อโซลูชันอื่น ๆ เหล่านั้นถูกนำไปใช้อย่างไม่ถูกต้อง ที่จุด "น่ารัก" นั่นคือฟรีฉันขอโทษ
มาตรฐาน SQL บอกว่าfull join on
เป็นinner join on
แถวที่union all
ไม่มีใครเทียบแถวซ้ายของตารางที่ขยายโดย nulls union all
แถวขวาของตารางที่ขยายโดย nulls เช่นinner join on
แถวunion all
แถวในleft join on
แต่ไม่inner join on
union all
แถวในแต่ไม่right join on
inner join on
เช่นleft join on
แถวแถวไม่ได้อยู่ในunion all
right join on
inner join on
หรือถ้าคุณรู้ว่าinner join on
ผลลัพธ์ของคุณไม่สามารถมีค่าว่างในคอลัมน์ตารางด้านขวาเฉพาะ " right join on
แถวที่ไม่ได้อยู่ในinner join on
" คือแถวที่right join on
มีon
เงื่อนไขที่ขยายโดยand
คอลัมน์is null
นั้น
เช่นแถวright join on
union all
ที่เหมาะสมในทำนองเดียวกันleft join on
จากความแตกต่างระหว่าง“INNER JOIN” และ“OUTER JOIN” คืออะไร? :
(SQL Standard 2006 SQL / Foundation 7.7 กฎไวยากรณ์ 1, กฎทั่วไป 1 b, 3 c & d, 5 b.)