使用左连接和右连接代替全连接 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.

 

 

 

 

 

 

 

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