在前兩篇文章中,我們都是使用的 2 張表,如果是 3 張表,結論會不會變呢?我們來試一下。
3. 3 張表,值不唯一的情況。
3.1 創建測試用表。
DROP TABLE IF EXISTS table1; CREATE TABLE table1 ( column_1 NUMERIC ); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (111); INSERT INTO table1 VALUES (111); DROP TABLE IF EXISTS table2; CREATE TABLE table2 ( column_2 NUMERIC ); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (23); INSERT INTO table2 VALUES (23); DROP TABLE IF EXISTS table3; CREATE TABLE table3 ( column_3 NUMERIC(30) ); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (333); INSERT INTO table3 VALUES (333); INSERT INTO table3 VALUES (23); INSERT INTO table3 VALUES (23);
查詢 3-2-1: 全連接
SELECT * FROM table1 t1 FULL OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 FULL OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 ORDER BY column_1, column_2, column_3;
輸出 3-2-1:
12 12
12 12
12 12
12 12
111
111
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
23
23
23
23
333
333
嘗試了多種辦法,直接給出最後的可行辦法:
查詢 3-2-2: 使用左連接、右連接、內連接模擬全連接。
SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 LEFT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 UNION ALL SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 RIGHT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 UNION ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 LEFT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 UNION ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 RIGHT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 EXCEPT ALL SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 INNER JOIN table3 t3 ON t1.column_1 = t3.column_3 EXCEPT ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 INNER JOIN table3 t3 ON t1.column_1 = t3.column_3 EXCEPT ALL SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.column_1 = t2.column_2 LEFT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 EXCEPT ALL SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.column_1 = t2.column_2 RIGHT OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 UNION ALL SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.column_1 = t2.column_2 INNER JOIN table3 t3 ON t1.column_1 = t3.column_3 ORDER BY column_1, column_2, column_3;
看上去很複雜。如果有更多的表,那就更復雜了。比如:
查詢 3-2-3: 複雜的全連接:
SELECT * FROM table1 t1 FULL OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 INNER OUTER JOIN table3 t3 ON t1.column_1 = t3.column_3 FULL OUTER JOIN table3 t3 ON t2.column_1 = t3.column_4 LEFT JOIN table3 t3 ON t2.column_1 = t3.column_4 ORDER BY column_1, column_2, column_3, column_4;
還有一個辦法是使用 view:
查詢 3-2-4:
DROP VIEW IF EXISTS join_1_2; CREATE VIEW join_1_2 AS SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 EXCEPT ALL SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.column_1 = t2.column_2 UNION ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 ORDER BY column_1, column_2; SELECT * FROM join_1_2 t1_2 LEFT OUTER JOIN table3 t3 ON t1_2.column_1 = t3.column_3 EXCEPT ALL SELECT * FROM join_1_2 t1_2 INNER JOIN table3 t3 ON t1_2.column_1 = t3.column_3 UNION ALL SELECT * FROM join_1_2 t1_2 RIGHT OUTER JOIN table3 t3 ON t1_2.column_1 = t3.column_3 ORDER BY column_1, column_2, column_3;
輸出 3-2-4:
12 12
12 12
12 12
12 12
111
111
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
123 123 123
23
23
23
23
333
333
解釋 3-2-4: 可以看出 3-2-1 的輸出和 3-2-4 的輸出是一致的。
經過測試,view table 的方法在 4 張表的情況下也是正確的,就不一一做實驗了,下面直接給出所有SQL:
DROP TABLE IF EXISTS table1 CASCADE; CREATE TABLE table1 ( column_1 NUMERIC ); INSERT INTO table1 VALUES (1); INSERT INTO table1 VALUES (1); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (13); INSERT INTO table1 VALUES (13); INSERT INTO table1 VALUES (14); INSERT INTO table1 VALUES (14); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (124); INSERT INTO table1 VALUES (124); INSERT INTO table1 VALUES (134); INSERT INTO table1 VALUES (134); INSERT INTO table1 VALUES (1234); INSERT INTO table1 VALUES (1234); DROP TABLE IF EXISTS table2 CASCADE; CREATE TABLE table2 ( column_2 NUMERIC ); INSERT INTO table2 VALUES (2); INSERT INTO table2 VALUES (2); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (23); INSERT INTO table2 VALUES (23); INSERT INTO table2 VALUES (24); INSERT INTO table2 VALUES (24); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (124); INSERT INTO table2 VALUES (124); INSERT INTO table2 VALUES (234); INSERT INTO table2 VALUES (234); INSERT INTO table2 VALUES (1234); INSERT INTO table2 VALUES (1234); DROP TABLE IF EXISTS table3 CASCADE; CREATE TABLE table3 ( column_3 NUMERIC ); INSERT INTO table3 VALUES (3); INSERT INTO table3 VALUES (3); INSERT INTO table3 VALUES (13); INSERT INTO table3 VALUES (13); INSERT INTO table3 VALUES (23); INSERT INTO table3 VALUES (23); INSERT INTO table3 VALUES (34); INSERT INTO table3 VALUES (34); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (134); INSERT INTO table3 VALUES (134); INSERT INTO table3 VALUES (234); INSERT INTO table3 VALUES (234); INSERT INTO table3 VALUES (1234); INSERT INTO table3 VALUES (1234); DROP TABLE IF EXISTS table4 CASCADE; CREATE TABLE table4 ( column_4 NUMERIC ); INSERT INTO table4 VALUES (4); INSERT INTO table4 VALUES (4); INSERT INTO table4 VALUES (14); INSERT INTO table4 VALUES (14); INSERT INTO table4 VALUES (24); INSERT INTO table4 VALUES (24); INSERT INTO table4 VALUES (34); INSERT INTO table4 VALUES (34); INSERT INTO table4 VALUES (124); INSERT INTO table4 VALUES (124); INSERT INTO table4 VALUES (134); INSERT INTO table4 VALUES (134); INSERT INTO table4 VALUES (234); INSERT INTO table4 VALUES (234); INSERT INTO table4 VALUES (1234); INSERT INTO table4 VALUES (1234); SELECT * FROM table1 t1; SELECT * FROM table2 t2; SELECT * FROM table2 t3; SELECT * FROM table2 t4; SELECT * FROM table1 t1 FULL OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 FULL OUTER JOIN table3 t3 ON t2.column_2 = t3.column_3 FULL OUTER JOIN table4 t4 ON t3.column_3 = t4.column_4 ORDER BY column_1, column_2, column_3, column_4; DROP VIEW IF EXISTS join_1_2 CASCADE; CREATE VIEW join_1_2 AS SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 EXCEPT ALL SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.column_1 = t2.column_2 UNION ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2; DROP VIEW IF EXISTS join_1_2_3 CASCADE; CREATE VIEW join_1_2_3 AS SELECT * FROM join_1_2 t1 LEFT OUTER JOIN table3 t3 ON t1.column_2 = t3.column_3 EXCEPT ALL SELECT * FROM join_1_2 t1 INNER JOIN table3 t3 ON t1.column_2 = t3.column_3 UNION ALL SELECT * FROM join_1_2 t1 RIGHT OUTER JOIN table3 t3 ON t1.column_2 = t3.column_3; DROP VIEW IF EXISTS join_1_2_3_4 CASCADE; CREATE VIEW join_1_2_3_4 AS SELECT * FROM join_1_2_3 t1 LEFT OUTER JOIN table4 t4 ON t1.column_3 = t4.column_4 EXCEPT ALL SELECT * FROM join_1_2_3 t1 INNER JOIN table4 t4 ON t1.column_3 = t4.column_4 UNION ALL SELECT * FROM join_1_2_3 t1 RIGHT OUTER JOIN table4 t4 ON t1.column_3 = t4.column_4; SELECT * FROM join_1_2_3_4 ORDER BY column_1 NULLS FIRST, column_2 NULLS FIRST, column_3 NULLS FIRST, column_4 NULLS FIRST;
MySQL 不支持 EXCEPT,可以使用 WHERE 達到相同的效果,SQL 如下:
DROP TABLE IF EXISTS table1 CASCADE; CREATE TABLE table1 ( column_1 NUMERIC ); INSERT INTO table1 VALUES (1); INSERT INTO table1 VALUES (1); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (12); INSERT INTO table1 VALUES (13); INSERT INTO table1 VALUES (13); INSERT INTO table1 VALUES (14); INSERT INTO table1 VALUES (14); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (123); INSERT INTO table1 VALUES (124); INSERT INTO table1 VALUES (124); INSERT INTO table1 VALUES (134); INSERT INTO table1 VALUES (134); INSERT INTO table1 VALUES (1234); INSERT INTO table1 VALUES (1234); DROP TABLE IF EXISTS table2 CASCADE; CREATE TABLE table2 ( column_2 NUMERIC ); INSERT INTO table2 VALUES (2); INSERT INTO table2 VALUES (2); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (12); INSERT INTO table2 VALUES (23); INSERT INTO table2 VALUES (23); INSERT INTO table2 VALUES (24); INSERT INTO table2 VALUES (24); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (123); INSERT INTO table2 VALUES (124); INSERT INTO table2 VALUES (124); INSERT INTO table2 VALUES (234); INSERT INTO table2 VALUES (234); INSERT INTO table2 VALUES (1234); INSERT INTO table2 VALUES (1234); DROP TABLE IF EXISTS table3 CASCADE; CREATE TABLE table3 ( column_3 NUMERIC ); INSERT INTO table3 VALUES (3); INSERT INTO table3 VALUES (3); INSERT INTO table3 VALUES (13); INSERT INTO table3 VALUES (13); INSERT INTO table3 VALUES (23); INSERT INTO table3 VALUES (23); INSERT INTO table3 VALUES (34); INSERT INTO table3 VALUES (34); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (123); INSERT INTO table3 VALUES (134); INSERT INTO table3 VALUES (134); INSERT INTO table3 VALUES (234); INSERT INTO table3 VALUES (234); INSERT INTO table3 VALUES (1234); INSERT INTO table3 VALUES (1234); DROP TABLE IF EXISTS table4 CASCADE; CREATE TABLE table4 ( column_4 NUMERIC ); INSERT INTO table4 VALUES (4); INSERT INTO table4 VALUES (4); INSERT INTO table4 VALUES (14); INSERT INTO table4 VALUES (14); INSERT INTO table4 VALUES (24); INSERT INTO table4 VALUES (24); INSERT INTO table4 VALUES (34); INSERT INTO table4 VALUES (34); INSERT INTO table4 VALUES (124); INSERT INTO table4 VALUES (124); INSERT INTO table4 VALUES (134); INSERT INTO table4 VALUES (134); INSERT INTO table4 VALUES (234); INSERT INTO table4 VALUES (234); INSERT INTO table4 VALUES (1234); INSERT INTO table4 VALUES (1234); SELECT * FROM table1 t1; SELECT * FROM table2 t2; SELECT * FROM table2 t3; SELECT * FROM table2 t4; # SELECT * # FROM table1 t1 # FULL OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 # FULL OUTER JOIN table3 t3 ON t2.column_2 = t3.column_3 # FULL OUTER JOIN table4 t4 ON t3.column_3 = t4.column_4 # ORDER BY column_1, column_2, column_3, column_4; DROP VIEW IF EXISTS join_1_2 CASCADE; CREATE VIEW join_1_2 AS SELECT * FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2 WHERE t2.column_2 IS NULL UNION ALL SELECT * FROM table1 t1 RIGHT OUTER JOIN table2 t2 ON t1.column_1 = t2.column_2; DROP VIEW IF EXISTS join_1_2_3 CASCADE; CREATE VIEW join_1_2_3 AS SELECT * FROM join_1_2 t1 LEFT OUTER JOIN table3 t3 ON t1.column_2 = t3.column_3 WHERE t3.column_3 IS NULL UNION ALL SELECT * FROM join_1_2 t1 RIGHT OUTER JOIN table3 t3 ON t1.column_2 = t3.column_3; DROP VIEW IF EXISTS join_1_2_3_4 CASCADE; CREATE VIEW join_1_2_3_4 AS SELECT * FROM join_1_2_3 t1 LEFT OUTER JOIN table4 t4 ON t1.column_3 = t4.column_4 WHERE t4.column_4 IS NULL UNION ALL SELECT * FROM join_1_2_3 t1 RIGHT OUTER JOIN table4 t4 ON t1.column_3 = t4.column_4; SELECT * FROM join_1_2_3_4 ORDER BY column_1, column_2, column_3, column_4;
結論:
多個表的 FULL OUTER JOIN 可以拆分成多個 2 個表的 JOIN,中間結果可以使用 VIEW.