加入三个表时记录数不匹配

时间:2014-01-17 18:24:03

标签: sql ms-access ms-access-2010

尽管我在互联网上找到了所有可能找到的材料,但我自己还没有能够解决这个问题。我是MS Access的新手,非常感谢任何指针。 这是我的问题 - 我有三张桌子

  1. Source1084 with columns - Department,Sub-Dept,Entity,Account,+ more more
  2. R12CAOmappingTable with columns - Account,R12_Account
  3. 表4列 - R12_Account,部门,子部门,实体,新部门,LOB +更多
  4. 我在Source中总共有1084条记录,结果表也必须包含1084条记录。我需要绘制一个表,其中包含来自R12CAOmappingTable + Table4中所有列的Source + R12_account中的所有列。

    这是我写的查询。这会生成正确的列,但会为我提供更多或更少的记录,并且可以交换不同的连接选项。

     SELECT rmt.r12_account,
           srb.version,
           srb.fy,
           srb.joblevel,
           srb.scenario,
           srb.department,
           srb.[sub-department],
           srb.[job function],
           srb.entity,
           srb.employee,
           table4.lob,
           table4.product,
           table4.newacct,
           table4.newdept,
           srb.[beg balance],
           srb.jan,
           srb.feb,
           srb.mar,
           srb.apr,
           srb.may,
           srb.jun,
           srb.jul,
           srb.aug,
           srb.sep,
           srb.oct,
           srb.nov,
           srb.dec,
           rmt.r12_account
    FROM   (source1084 AS srb
            LEFT JOIN r12caomappingtable AS rmt
                   ON srb.account = rmt.account)
           LEFT JOIN table4
                  ON ( srb.department = table4.dept )
                     AND ( srb.[sub-department] = table4.subdept )
                     AND ( srb.entity = table4.entity )
    WHERE  ( ( ( srb.[sub-department] ) = table4.subdept )
             AND ( ( srb.entity ) = table4.entity )
             AND ( ( rmt.r12_account ) = table4.r12_account ) );  
    

3 个答案:

答案 0 :(得分:1)

在这个简单示例中,Table1包含3行,其中包含唯一的fld1值。 Table2包含一行,该行中的fld1值与Table1中的一个匹配。因此,此查询返回3行。

SELECT *
FROM
    Table1 AS t1
    LEFT JOIN Table2 AS t2
    ON t1.fld1 = t2.fld1;

但是,如果我添加WHERE子句,如下所示,该查询版本只返回一行--- fld1值匹配的行。

SELECT *
FROM
    Table1 AS t1
    LEFT JOIN Table2 AS t2
    ON t1.fld1 = t2.fld1
WHERE t1.fld1 = t2.fld1;

换句话说,WHERE子句抵消了LEFT JOIN,因为它排除了t2.fld1为空的行。如果这是有道理的,请注意第二个查询在功能上等同于......

SELECT *
FROM
    Table1 AS t1
    INNER JOIN Table2 AS t2
    ON t1.fld1 = t2.fld1;

你的情况很相似。我建议您首先删除WHERE子句并确认此查询至少返回您预期的1084行。

SELECT Count(*) AS CountOfRows
FROM   (source1084 AS srb
        LEFT JOIN r12caomappingtable AS rmt
               ON srb.account = rmt.account)
       LEFT JOIN table4
              ON ( srb.department = table4.dept )
                 AND ( srb.[sub-department] = table4.subdept )
                 AND ( srb.entity = table4.entity );

在查询返回正确的行数后,您可以更改SELECT列表以返回所需的列。但是,在您获得正确的行之前,列不是真正的问题。

答案 1 :(得分:0)

在不知道您的表值的情况下,很难对您的问题给出完整的答案。根据您描述的方式导致问题的问题。更可能的是基于您正在使用的联接类型。

我发现了解你应该使用什么类型连接的最佳方法是引用一个维恩图来解释你可以使用的不同类型的连接。

enter image description here

Jeff Atwood也使用上述方法对his site上的SQL连接做了很好的解释。

答案 2 :(得分:0)

最好只使用查询构建器。放在主表中。选择所需的列。现在,对于任何其他查找值,只需简单地放入其他表,绘制连接线,双击并使用左连接。您可以为需要“抓取”或从其他表中查找其他值的2或30列执行此操作。返回的基表中ORIGINAL行的数量应始终保持不变。

所以只需使用查询构建器并按照上面的说明操作即可。

你发布的SQL的问题是你在内部嵌入了连接()。不要那样做。 (或者让查询构建器为您执行此操作 - 它们往往非常混乱,但也可以工作)。

请使用:

FROM   source1084 AS srb
LEFT JOIN r12caomappingtable AS rmt
       ON srb.account = rmt.account
LEFT JOIN table4
          ON ( srb.department = table4.dept )
             AND ( srb.[sub-department] = table4.subdept )
             AND ( srb.entity = table4.entity )

如上所述,我不明白为什么你在where子句中再次“重复”这些条件。