2010-12-20 42 views
0

我已经创建在MS Access查询来模拟FULL OUTER JOIN和合并,看起来像下面这样的结果:MS访问SQL:麻烦UNION将所有与LEFT JOIN

SELECT NZ(estimates.employee_id, actuals.employee_id) AS employee_id 
, NZ(estimates.a_date, actuals.a_date) AS a_date 
, estimates.estimated_hours 
, actuals.actual_hours 
FROM (SELECT * 
     FROM estimates 
     LEFT JOIN actuals ON estimates.employee_id = actuals.employee_id 
     AND estimates.a_date = actuals.a_date 
     UNION ALL 
     SELECT * 
     FROM estimates 
     RIGHT JOIN actuals ON estimates.employee_id = actuals.employee_id 
     AND estimates.a_date = actuals.a_date 
     WHERE estimates.employee_id IS NULL 
     OR estimates.a_date IS NULL) AS qFullJoinEstimatesActuals 

我有救这个查询作为一个对象(我们称之为qEstimatesAndActuals)。我的目标是与另一张桌子左边加入qEstimatesAndActuals。类似以下内容:

SELECT * 
FROM qJoinedTable 
LEFT JOIN (SELECT * 
      FROM labor_rates) AS rates 
ON qJoinedTable.employee_id = rates.employee_id 
    AND qJoinedTable.a_date BETWEEN rates.begin_date AND rates.end_date 

MS Access接受语法并运行查询,但它省略了明显在结果集内的结果。想知道如果日期格式不知何故丢失,我在begin_date和end_date周围放置了一个FORMAT,以强制它们被解释为Short Dates。奇怪的是,这产生了不同的结果集,但它仍然省略了它不应该有的结果。

我想知道如果查询是以这样的方式执行,你不能左加入一个UNION ALL的结果集。有没有人对此有过任何想法/想法?有没有更好的方式来实现最终目标?

回答

0

周围日期的古怪行为相一致,这个问题竟然是与使用新西兰的选择从qFullJoinEstimatesActuals日期。 NZ的使用似乎使数据类型不明确。这样,从在我的主题的示例下面的行引起错误:

, NZ(estimates.a_date, actuals.a_date) AS a_date 

a_date的歧义数据类型引起BETWEEN运算以产生错误的结果进行比较a_date时rates.begin_date和rates.end_date在左加入。这件事是通过型铸造NZ函数的结果解决,如下:

, CDate(NZ(estimates.a_date, actuals.a_date)) AS a_date 
+0

我也对Nz()的返回类型的不可靠性感到沮丧,但是根据定义,你期望其中的一个参数至少有一些时间是空的,这意味着函数需要在返回类型或检查有关源数据的元数据。所以,你必须自己做。也就是说,Nz()表达式的连接会让我感到困难,因为它不能使用索引。 – 2010-12-21 02:32:01

+0

这篇文章基于向UNION ALLs展示,这很合理。你只有一个。你怎么能得到所有的结果? – IamIC 2010-12-21 04:31:35

+0

@ David-W-Fenton这当然是有道理的。至于设计上的问题,你有另外一个建议吗?通过略微简化,有两个表格:(1)包含employee_id,week_end_date和projected_hours的估计表,以及(2)具有employee_id,week_end_date和actual_hours的实际表。可能有员工预计会工作,但不会。同样,可能有员工没有投入工作,但是这样做。目标:将employee_id,week_end_date,projected_hours,actual_hours获取到单个可查询对象中。例如,001,9/26/2010,0,10 – Adam 2010-12-21 16:39:05

0

您可以准确地找到如何做到这一点here

您错过了INNER JOIN .... UNION ALL步骤。

+0

你引用被用作FULL基础的文章JOIN(虽然我修改了语法删除使用的冗余内部联接 - 因为一些评论这篇文章的人可以完成)。但是,创建FULL JOIN的语法不是*我遇到的问题。我上面描述的问题是指当FULL JOIN(它自己工作)的结果集与LEFT JOIN结合时产生的结果集。 – Adam 2010-12-20 22:26:21

+0

看看文章中的维恩图。在撰写文章时,作者使用三个查询来获取集合1(INNER JOIN),集合2(LEFT JOIN用WHERE子句删除集合1的结果)和集合3(RIGHT JOIN用WHERE子句删除集合1结果)并使用两个UNION ALL来组合它们。这可以通过使用两个查询来更简单地完成,第一个查询获得集合1和2(LEFT JOIN *不带* WHERE子句来移除集合1的结果),第二个获得集合3(RIGHT JOIN用WHERE子句去除设置1结果)并使用一个UNION ALL来合并它们。 – Adam 2010-12-21 16:53:17

+0

@亚当谢谢。出于好奇,为什么不使用SQL Server? – IamIC 2010-12-21 16:56:18

1

我会尝试将查询的每个部分分解为其自己的访问查询对象,例如,

SELECT * 
    FROM estimates 
    LEFT JOIN actuals ON estimates.employee_id = actuals.employee_id 
    AND estimates.a_date = actuals.a_date 

将qryOne

SELECT * 
    FROM estimates 
    RIGHT JOIN actuals ON estimates.employee_id = actuals.employee_id 
    AND estimates.a_date = actuals.a_date 
    WHERE estimates.employee_id IS NULL 
    OR estimates.a_date IS NULL 

将qryTwo

SELECT * FROM qryOne 
UNION ALL 
SELECT * FROM qryTwo 

会qryFullJoinEstimatesActuals,终于

SELECT NZ(estimates.employee_id, actuals.employee_id) AS employee_id 
, NZ(estimates.a_date, actuals.a_date) AS a_date 
, estimates.estimated_hours 
, actuals.actual_hours 
FROM qryFullJoinEstimatesActuals 

我发现,结构不在复杂的Access S中工作如果将QL语句分解为单个查询对象并逐步重新组合,则QL语句通常可以正常工作。另外,您可以单独测试查询的每个部分。如果证明有必要,这将帮助您找到解决方法。

+0

感谢您的提示。虽然这不是根本问题,但它(a)导致我偶然发现了另一个无关的错误,这个错误稍后会成为问题,并且(b)帮助我将注意力集中在导致问题的原因上。 – Adam 2010-12-20 23:37:13