MS Access - 替代为具有相同名称的列执行“完全连接”

时间:2013-07-25 14:39:16

标签: sql ms-access

我有使用访问权限的问题:我使用RIGHT + LEFT外连接来克服ACCESS不支持FULL JOIN这一事实。

SELECT *
FROM T1 RIGHT OUTER JOIN T2
ON T1.xxx = T2.xxx 
UNION 
SELECT *
FROM T1 LEFT OUTER JOIN T2
ON T1.xxx = T2.xxx 

在这些表格上:

T1:
ID1 | xxx | fieldA
a     1       X
b     2       Y
c     3       Z

T2:
ID2 | xxx | fieldB
d      2       K
e      3       J
f      4       H

结果我获得了一个具有这种结构的表

T1.xxx | T2.xxx | fieldA | fieldB | ID1 | ID2
   1                 X               a
   2        2        Y       K       b     d
   3        3        Z       J       c     e
            4                H             f

xxx不是主键,但具有相同的名称和数字类型(整数)

我从许多其他地方看到,这应该通过折叠两张桌子来实现!这里没有(相同行上的元素,当非空白时,当然是相同的)

我的期望

FINAL TABLE:
    xxx |  ID1 | ID2 |fieldA | fieldB
     1      a            X
     2      b     d      Y       K
     3      c     e      Z       J
     4            f              H

4 个答案:

答案 0 :(得分:1)

这两个表似乎都有不同的列值集,您可能t1.xxxt2.xxx具有相同的值,但其他列不是{{1在这种情况下,不会合并这两个记录

尝试类似

的内容
union

这样的内容应该为您提供表1 表2 中的所有SELECT T1.xxx FROM T1 RIGHT OUTER JOIN T2 ON T1.xxx = T2.xxx UNION SELECT T2.xxx FROM T1 LEFT OUTER JOIN T2 ON T1.xxx = T2.xxx 值,忽略xxx的值duplicate }。

答案 1 :(得分:0)

您观察到的行为最可能的解释是返回的行不相同,它们不是完全相同的。

UNION运算符将删除重复的行,但它不会对“折叠表”执行任何操作。


要获取指定的结果集(在更新的问题中),这里有一个返回结果的SQL模式。 (我不知道Access是否支持此功能,但这可以在MySQL,SQL Server,Oracle等中使用。)

 SELECT i.xxx
      , v1.ID AS ID1
      , v2.ID AS ID2   
      , v1.fieldA AS fieldA   
      , v2.fieldB AS fieldB   
   FROM (
          SELECT t1.xxx AS xxx
            FROM T1 t1
           UNION
          SELECT t2.xxx
            FROM T2 t2
        ) i
   LEFT
   JOIN T1 v1
     ON v1.xxx = i.xxx
   LEFT
   JOIN T2 v2
     ON v2.xxx = i.xxx

(注意:如果不保证xxx在每个表中都是唯一的,那么此查询可能会生成重复的行。)

答案 2 :(得分:0)

我的解决方案(绝对不优雅):

SELECT [QUERY1].XX, ID1, ID2, fieldA, fieldB
FROM (T2 RIGHT JOIN [QUERY1] ON T2.xxx = [QUERY1].XX) LEFT JOIN T1 ON [QUERY1].XX = T1.XX;

其中QUERY1如下:

(SELECT CInt(NZ(T1.xxx,T2.xxx)) as XX
    FROM T1 RIGHT OUTER JOIN T2
    ON T1.xxx = T2.xxx
    UNION 
    SELECT CInt(NZ(T1.xxx,T2.xxx)) as XX 
    FROM T1 LEFT OUTER JOIN T2
    ON T1.xxx = T2.xxx)
    UNION (SELECT CInt(NZ(T2.xxx,T1.xxx))  as xx1
    FROM T1 RIGHT OUTER JOIN T2
    ON T1.xxx = T2.xxx
    UNION 
    SELECT CInt(NZ(T2.xxx,T1.xxx)) as xx1
    FROM T1 LEFT OUTER JOIN T2
    ON T1.xxx = T2.xxx);

请注意,xx1未使用,甚至未在表格中显示

答案 3 :(得分:0)

尝试这一个:我尝试过并获得两个结果集。

DECLARE @T1 TABLE
(
ID1 VARCHAR(2) ,XXX INT, FIELDA VARCHAR(2)
)
DECLARE @T2 TABLE
(
ID2 VARCHAR(2) ,XXX INT, FIELDB VARCHAR(2)
)


INSERT INTO @T1 VALUES 
('a',     1,       'X'),
('b',     2,       'Y'),
('c',     3,       'Z')

INSERT INTO @T2 VALUES 
('d',     2,       'k'),
('e',     3,       'j'),
('f',     4,       'h')

SELECT
    ISNULL(CONVERT(VARCHAR(1),T1.xxx),' ') AS [T1.xxx] , 
    ISNULL(CONVERT(VARCHAR(1),T2.xxx),'') AS [T2.xxx] , 
    ISNULL(fieldA,'') AS [fieldA], 
    ISNULL(fieldB,'') AS [fieldB] , 
    ISNULL(ID1,'') AS [ID1] , 
    ISNULL(ID2,'') AS [ID2]
FROM 
(
    SELECT XXX as XXX1 FROM @T1
    UNION
    SELECT XXX as XXX1  FROM @T2
)T LEFT OUTER JOIN 
@T1 T1 ON T.XXX1 = T1.XXX 
LEFT OUTER JOIN
@T2 T2 ON T.XXX1 = T2.XXX

---------------------- RESULT ------------------

T1.xxx  T2.xxx  ID1 ID2 fieldA  fieldB
1       a       X   
2   2   b   d   Y   k
3   3   c   e   Z   j
    4       f       h

SELECT
    ISNULL(CONVERT(VARCHAR(1),T.xxx1),' ') AS [xxx] ,
    ISNULL(ID1,'') AS [ID1] ,   
    ISNULL(ID2,'') AS [ID2],
    ISNULL(fieldA,'') AS [fieldA], 
    ISNULL(fieldB,'') AS [fieldB] 

FROM 
(
    SELECT XXX as XXX1 FROM @T1
    UNION
    SELECT XXX as XXX1  FROM @T2
)T LEFT OUTER JOIN 
@T1 T1 ON T.XXX1 = T1.XXX 
LEFT OUTER JOIN
@T2 T2 ON T.XXX1 = T2.XXX

---------------------- RESULT ------------------

xxx ID1 ID2 fieldA  fieldB
1   a       X   
2   b   d   Y   k
3   c   e   Z   j
4       f       h