2

我已经问过一个类似的问题,但我现在已经简化了表/查询,足以建立一个具有(希望)描述性命名的示例数据库:

https://docs.google.com/file/d/0B2PZcGkhNyd4THpWa01fTjVvSWM/edit?usp=sharing

有一个查询,ChainsCasesPerMonthPerStorePreviousMonthRange,可以正常工作。它从两个表和 QueryDatesPrevious 查询中获取数据,以将上一期间的数据返回到 QueryDates 表中指定的数据。到目前为止,一切似乎都很好。

但是当我运行查询 LeftJoinReturnsError 时,Chains 表中的三个额外链返回 #Error 而不是返回预期的 Null。

如果我将 QueryDatesPrevious 从查询更改为表,一切正常,所以这似乎是问题所在,但我似乎无法解决它,即使使用 Iif(IsNull, Null, 0) 条件。

只要我能弄清楚如何转移它们,解决它的人就会额外获得 50 个代表点。:)

(如果您有兴趣,上一个问题:Access 2007 - Left Join to a query 返回 #Error 而不是 Null

-- 编辑更新 --

输出看起来像这样,虽然我不记得我放入测试数据库的确切数据:

Chain                 CasesPerMonthPerStore
AgriStore             2.33
Agricultural Export   
2B Pencils            3.6
Bob's Markets         

因此,基本上,Chain 表中不在其他表中的任何链都应返回 Null 作为左连接的一部分。

4

3 回答 3

2

这也很丑陋,但它似乎有效:

运行以下查询以创建名为 [tblChainsCasesPerMonthPerStorePreviousMonthRange] 的表:

SELECT ChainsCasesPerMonthPerStorePreviousMonthRange.* 
INTO tblChainsCasesPerMonthPerStorePreviousMonthRange
FROM ChainsCasesPerMonthPerStorePreviousMonthRange;

创建一个名为 [updChainsCasesPerMonthPerStorePreviousMonthRange] 的查询作为更新查询,将 [ChainsCasesPerMonthPerStorePreviousMonthRange] 的结果保存到 [tblChainsCasesPerMonthPerStorePreviousMonthRange] 中:

INSERT INTO tblChainsCasesPerMonthPerStorePreviousMonthRange
SELECT ChainsCasesPerMonthPerStorePreviousMonthRange.*
FROM ChainsCasesPerMonthPerStorePreviousMonthRange;

将以下函数粘贴到标准 VBA 模块中

Public Function RemakeTable() As Variant
Dim qdf As DAO.QueryDef
Debug.Print "Executing RemakeTable()..."
CurrentDb.Execute "DELETE FROM tblChainsCasesPerMonthPerStorePreviousMonthRange", dbFailOnError
Set qdf = CurrentDb.QueryDefs("updChainsCasesPerMonthPerStorePreviousMonthRange")
qdf.Execute
Set qdf = Nothing
RemakeTable = Null
End Function

将您的 [LeftJoinReturnsError] 查询更新为

SELECT 
    Chains.Chain, 
    tblChainsCasesPerMonthPerStorePreviousMonthRange.CasesPerMonthPerStore,
    RemakeTable() AS Junk
FROM 
    Chains 
    LEFT JOIN 
    tblChainsCasesPerMonthPerStorePreviousMonthRange 
        ON Chains.Chain=tblChainsCasesPerMonthPerStorePreviousMonthRange.Chain;

最终查询有一个名为 [Junk] 的额外列,但至少我们得到了想要的结果。

注意:我将 放在Debug.PrintVBA 函数中以验证它只被调用一次,而不是查询中的每一行调用一次。

于 2013-06-23T23:37:25.807 回答
1

关于错误的好帖子。我没有看到,但很明显这正是正在发生的事情。由于 Access 不支持横向连接或 SQL Server 的 APPLY 子句,我可以看到处理它的唯一方法是将表达式提升到顶级查询中的 select 子句。以下为您提供所需的输出:

SELECT Chains.Chain, (SELECT ChainsCasesPerMonthPerStorePreviousMonthRange.CasesShipped/(DateDiff("m",ChainsCasesPerMonthPerStorePreviousMonthRange.StartDatePrevious,ChainsCasesPerMonthPerStorePreviousMonthRange.EndDatePrevious)+1)/ChainsCasesPerMonthPerStorePreviousMonthRange.NumberOfStores AS Expr1 from ChainsCasesPerMonthPerStorePreviousMonthRange WHERE ChainsCasesPerMonthPerStorePreviousMonthRange.Chain = Chains.Chain) as Expr2
FROM Chains;

这很丑陋,但它有效。当然,在 SQL Server 或其他数据库中,您不需要横向连接,因为进程外部连接与表达式正确。

于 2013-06-23T17:49:54.513 回答
1

好的,所以我设置了另一个查询,它只返回应该为 CasesPerMonthPerStore 返回 Null 值的链,但实际上在我的测试数据库中返回 #Error:

SELECT Chains.Chain
FROM Chains LEFT JOIN ChainsNumStoresPreviousMonthRange ON Chains.Chain = ChainsNumStoresPreviousMonthRange.Chain
WHERE ChainsNumStoresPreviousMonthRange.NumberOfStores Is Null;

因此,在上述问题的书面示例中,此查询将返回:

Chain
Agricultural Export
Bob's Markets

然后我将这些链连同一个 Null 字段联合到返回所有确实返回 CasesPerMonthPerStore 值的链的查询中:

SELECT *
FROM (SELECT ChainsCasesPerMonthPerStorePreviousMonthRange.Chain, ChainsCasesPerMonthPerStorePreviousMonthRange.CasesPerMonthPerStore
FROM ChainsCasesPerMonthPerStorePreviousMonthRange
UNION ALL
SELECT ChainsNotInPreviousPeriod.Chain, NULL
FROM ChainsNotInPreviousPeriod)  AS UnionQuery
ORDER BY Chain;

所以秘密似乎是将计算字段与左连接分开。这是我第一次遇到这个错误,我不知道这种方法是否适用于所有情况,但它对我有用。:)

感谢您的时间布赖恩和戈德,

于 2013-06-24T09:25:37.980 回答