在两个以上的表上使用Access模拟FULL OUTER JOIN

时间:2014-07-11 15:06:07

标签: ms-access full-outer-join

我学到了Access不允许你进行完全外部连接的困难方式,在阅读如何模拟一个时,我已经开始明白如何这样做,但是我在尝试将此应用于只有两张桌子。

是否像执行以下操作一样简单?

SELECT * FROM table1
LEFT JOIN table2 ON table1.field = table2.field
LEFT JOIN table3 ON table1.field = table3.field
UNION
SELECT * FROM table1
RIGHT JOIN table2 ON table1.field = table2.field
RIGHT JOIN table3 ON table1.field = table3.field

1 个答案:

答案 0 :(得分:4)

对网络的快速搜索显示,在Stack Overflow和其他地方已多次讨论模拟FULL OUTER JOIN(" FOJ")的主题,但答案似乎都局限于只有两个表的情况。我怀疑这是因为三张或更多桌子上的FOJ是

  1. 不常见,
  2. 可能很乱。
  3. 尽管如此,我还以为我试一试,这就是我想出的:

    在两个表上模拟FOJ最常提到的技术是UNION ALL三种可能的情况:

    In_Table2  In_Table1
    ---------  ---------
    false      true
    true       false
    true       true
    

    或代替true = 1和false = 0

    In_Table2  In_Table1
    ---------  ---------
    0          1
    1          0
    1          1
    

    看起来像一个两位整数,有三个可能的非零值,而提取它们的SQL将是

    形式
    Table2 RIGHT JOIN Table1 WHERE Table2.something IS NULL
    UNION ALL
    Table2 LEFT JOIN Table1 WHERE Table1.something IS NULL
    UNION ALL
    Table2 INNER JOIN Table1
    

    具有三个表的情况的状态表因此看起来像一个三位整数,具有七个可能的非零值

    In_Table3  In_Table2  In_Table1
    ---------  ---------  ---------
    0          0          1
    0          1          0
    0          1          1
    1          0          0
    1          0          1
    1          1          0
    1          1          1
    

    我想在整数值上进行连接,所以我只为七行中的每一行按顺序分配它们

    Table3  Table2  Table1
    ------  ------  ------
                    1
            2       
            3       3
    4               
    5               5
    6       6       
    7       7       7
    

    所以我的测试表是

    [表1]

    n  txt 
    -  ----
    1  t1_1
    3  t1_3
    5  t1_5
    7  t1_7
    

    [表2]

    n  txt 
    -  ----
    2  t2_2
    3  t2_3
    6  t2_6
    7  t2_7
    

    [表3]

    n  txt 
    -  ----
    4  t3_4
    5  t3_5
    6  t3_6
    7  t3_7
    

    我在Access中创建了一个名为[foj12]的已保存查询,以执行[Table1]和[Table2]之间的FOJ

        SELECT t1.n AS t1_n, t1.txt AS t1_txt, t2.n AS t2_n, t2.txt AS t2_txt
        FROM
            Table1 t1
            INNER JOIN
            Table2 t2
                ON t1.n = t2.n
    UNION ALL
        SELECT t1.n AS t1_n, t1.txt AS t1_txt, t2.n AS t2_n, t2.txt AS t2_txt
        FROM
            Table1 t1
            LEFT JOIN
            Table2 t2
                ON t1.n = t2.n
        WHERE t2.n IS NULL
    UNION ALL 
        SELECT t1.n AS t1_n, t1.txt AS t1_txt, t2.n AS t2_n, t2.txt AS t2_txt
        FROM
            Table1 t1
            RIGHT JOIN
            Table2 t2
                ON t1.n = t2.n
        WHERE t1.n IS NULL
    

    返回

    t1_n  t1_txt  t2_n  t2_txt
    ----  ------  ----  ------
       1  t1_1                
                     2  t2_2  
       3  t1_3       3  t2_3  
       5  t1_5                
                     6  t2_6  
       7  t1_7       7  t2_7  
    

    然后我开始研究涉及[表3]的案例。它们如下,并且对应于"联合"在下面的SQL语句中查询。

    1. 表3匹配表1和表2(n = 7)
    2. 表3匹配表1但不匹配表2(n = 5)
    3. 表3匹配表2但不匹配表1(n = 6)
    4. 表3中的
    5. 行与表1或表2中的任何内容不匹配(n = 4)
    6. FOJ中的
    7. 行(表1,表2)与表3没有任何共同之处(n = 1,2,3)
    8.     SELECT f.t1_n, f.t1_txt, f.t2_n, f.t2_txt, t3.n AS t3_n, t3.txt AS t3_txt
          FROM
              Table3 t3
              INNER JOIN
              foj12 f
                  ON t3.n = f.t1_n AND t3.n = f.t2_n
      UNION ALL
          SELECT f.t1_n, f.t1_txt, f.t2_n, f.t2_txt, t3.n AS t3_n, t3.txt AS t3_txt
          FROM
              Table3 t3
              INNER JOIN
              foj12 f
                  ON t3.n = f.t1_n
          WHERE f.t2_n IS NULL
      UNION ALL
          SELECT f.t1_n, f.t1_txt, f.t2_n, f.t2_txt, t3.n AS t3_n, t3.txt AS t3_txt
          FROM
              Table3 t3
              INNER JOIN
              foj12 f
                  ON t3.n = f.t2_n
          WHERE f.t1_n IS NULL
      UNION ALL
          SELECT NULL, NULL, NULL, NULL, t3.n AS t3_n, t3.txt AS t3_txt
          FROM
              Table3 t3
          WHERE t3.n NOT IN (SELECT t1_n FROM foj12 WHERE t1_n IS NOT NULL)
              AND t3.n NOT IN (SELECT t2_n FROM foj12 WHERE t2_n IS NOT NULL)
      UNION ALL
          SELECT f.t1_n, f.t1_txt, f.t2_n, f.t2_txt, NULL, NULL
          FROM foj12 f
          WHERE 
              (f.t1_n NOT IN (SELECT n FROM Table3) AND f.t2_n NOT IN (SELECT n FROM Table3))
              OR
              (f.t1_n NOT IN (SELECT n FROM Table3) AND f.t2_n IS NULL)
              OR
              (f.t1_n IS NULL AND f.t2_n NOT IN (SELECT n FROM Table3))
      ORDER BY 5, 3, 1
      

      那个小小的美丽回归

      t1_n  t1_txt  t2_n  t2_txt  t3_n  t3_txt
      ----  ------  ----  ------  ----  ------
         1  t1_1                              
                       2  t2_2                
         3  t1_3       3  t2_3                
                                     4  t3_4  
         5  t1_5                     5  t3_5  
                       6  t2_6       6  t3_6  
         7  t1_7       7  t2_7       7  t3_7  
      

      (毋庸置疑,我对添加第四张桌子并不感兴趣!)

      欢迎评论。