显示两个表之间不同的行 - MS Access

问题描述

我一直在尝试转换以下 sql-Server 代码,以在 MS Access 中获得类似的结果。

WITH TableA(Col1,Col2,Col3) 
     AS (SELECT 'Dog',1,1     UNION ALL 
         SELECT 'Cat',27,86   UNION ALL 
         SELECT 'Cat',128,92),TableB(Col1,105  UNION ALL 
         SELECT 'Lizard',83,NULL) 
SELECT CA.*
FROM   TableA A 
       FULL OUTER JOIN TableB B 
         ON A.Col1 = B.Col1 
            AND A.Col2 = B.Col2 
/*Unpivot the joined rows*/
CROSS APPLY (SELECT 'TableA' AS what,A.* UNION ALL
             SELECT 'TableB' AS what,B.*) AS CA     
/*Exclude identical rows*/
WHERE  EXISTS (SELECT A.* 
               EXCEPT 
               SELECT B.*) 
/*discard NULL extended row*/
AND CA.Col1 IS NOT NULL      
ORDER BY CA.Col1,CA.Col2

给予

what   Col1   Col2        Col3
------ ------ ----------- -----------
TableA Cat    27          86
TableB Cat    27          105
TableA Cat    128         92
TableB Lizard 83          NULL

到目前为止,我已经能够使用以下代码转换获取 FULL OUTER JOIN 的复制,但我一直无法复制旋转联合行(CROSS APPLY)。

(SELECT *
FROM TableA AA
        INNER JOIN TableB BB ON AA.Col1 = BB.Col1
UNION ALL
SELECT *
    FROM  TableA  AA
        LEFT JOIN TableB BB  ON AA.Col1 = BB.Col1
    WHERE BB.[IP Number] IS NULL
UNION ALL
SELECT *
    FROM  TableA AA
        RIGHT JOIN TableB BB ON AA.Col1 = BB.Col1
    WHERE AA.Col1 IS NULL 
) 

我可以使用一些帮助在 MS-Access 查询中实现相同的结果。

解决方法

据我所知,您有两个具有唯一行的表。您想返回存在于一个表中但不在另一个表中的行。

我建议在这两个数据库中进行聚合和 HAVING

SELECT col1,col2,col3
FROM ((SELECT col1,col3 FROM TableA) UNION ALL
      (SELECT col1,col3 FROM TableB)
     ) as ab
GROUP BY col1,col3
HAVING COUNT(*) = 1;

或者,两个 NOT EXISTS 子句:

SELECT a.*
FROM TableA as a
WHERE NOT EXISTS (SELECT 1
                  FROM TableB as b
                  WHERE (a.col1 = b.col1 OR a.col1 IS NULL AND b.col1 IS NULL) AND
                        (a.col2 = b.col2 OR a.col2 IS NULL AND b.col2 IS NULL) AND
                        (a.col3 = b.col3 OR a.col3 IS NULL AND b.col3 IS NULL) 
                 )
UNION ALL
SELECT b.*
FROM TableB as b
WHERE NOT EXISTS (SELECT 1
                  FROM TableA as a
                  WHERE (a.col1 = b.col1 OR a.col1 IS NULL AND b.col1 IS NULL) AND
                        (a.col2 = b.col2 OR a.col2 IS NULL AND b.col2 IS NULL) AND
                        (a.col3 = b.col3 OR a.col3 IS NULL AND b.col3 IS NULL) 
                 );

Here 是一个 dbfiddle,使用 SQL Server,但语法在 MS Access 中应该基本相同。