使用左連接和右連接代替全連接 3 (3 張表,值不唯一)(4張表)(統一結論)

在前兩篇文章中,我們都是使用的 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.

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章