2013-06-18 26 views
1

這個問題類似,但它們與查詢問題一直沒有完全解決:Access 2007年 - 左加入到查詢返回#錯誤,而不是空

#Error showing up in multiple LEFT JOIN statement Access query when value should be NULL

我得到#錯誤,當我期待看到一個空做左連接在沒有相應的記錄上的右側時加入:

Chain    CasesPerMonthPerStore MonthOfFirstOrder 
Naturally   2.3      5/1/2011 
Tom's Market  #Error 
Livingstons   #Error 
EverClear   3.1      7/1/2012 
Bob's Market  2.66     5/1/2012 
Andy's Exports  #Error 
Jamestowns   0.89     7/1/2012 

,如果我將數據複製到一個表,並留下加入到這個表它工作正常,所以我認爲t的語法有錯誤他查詢:

SELECT 
    MonthRange.Chain, 
    MonthRange.CasesShipped/IIf(MonthsSinceFirstOrder.Months>DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1, 
           DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1, 
           MonthsSinceFirstOrder.Months)/NumStores.NumberOfStores AS CasesPerMonthPerStore, 
    MonthsSinceFirstOrder.MonthOfFirstOrder 
FROM 
    QueryDates, 
    (
     MonthRange 
     INNER JOIN 
     NumStores 
      ON MonthRange.Chain=NumStores.Chain 
    ) 
    INNER JOIN 
    MonthsSinceFirstOrder 
     ON MonthRange.Chain=MonthsSinceFirstOrder.Chain; 

這個SQL返回正確的結果,它只是它的行爲,當左連接到它返回#Errors。

nb中間的奇怪Iif語句檢查自第一個訂單以來的月數是否大於指定日期範圍中包含的月數 - 所以如果日期範圍有6個月並且第一個訂單在結束日期前9個月,它使用6;如果第一個命令是在結束日期之前只有4個月,它採用4

- 編輯更新 -

對,我把查詢內容由一個一個出來,這是最簡單的我可以得到同時仍重建左連接錯誤:

SELECT 
    MonthRange.Chain, 
    DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore 
FROM 
    QueryDates, 
    MonthRange; 

這就是我如何左側的接合部它:

SELECT 
    Chains.Chain, 
    ErrorQuery.CasesPerMonthPerStore 
FROM 
    Chains 
    LEFT JOIN 
    ErrorQuery 
     ON Chains.Chain=ErrorQuery.Chain; 

是否在此SQL看什麼錯?

+0

使用最少的情況下[MonthRange],[QueryDates]和[鏈]都是表我無法重建問題。 *您的案件中是否存有*這些保存的查詢? –

+0

是的,有幾層嵌套查詢可以實現這一目標。我會檢查這些查詢並查看是否有任何錯誤。在過去,我在某個領域進行分組時遇到了問題,然後從Select語句中刪除了該字段,但將其留在了group by子句中。 Access並沒有採用這種方式,並且在大多數情況下它運行良好,但在某些情況下它會引發奇怪的結果。如果我瞭解它的底部,我會在這裏發佈答案,謝謝你花時間檢查上面的查詢。 – Wilskt

回答

1

它看起來像它可能是在訪問一個已知的bug,從而使得上外的錯誤做計算字段加入:

http://allenbrowne.com/BugOuterJoinExpression.html

http://allenbrowne.com/bug-10.html

所以去看看我是否可以重新調整子查詢來以某種方式掩飾計算的字段。

訪問。 :)

+0

RE:「以某種方式僞裝計算的字段」 - 在我重新創建示例數據庫中的錯誤之後,我一直在思考相同的問題。我的猜測是計算列是靜態的(總是返回相同的值),所以查詢優化器將外部聯接「短路」,併爲每一行返回該值。無論如何,感謝您發佈您的答案;它可能會在稍後幫助其他人。 –

+1

在我的測試示例中,如果我將計算字段切換爲常量(例如3或「測試」),那麼對於每個鏈確實都會出現該值,無論它們是否出現在連接的右側。對於計算字段,它返回一個錯誤。只有當它直接引用單個字段時才能正常工作。如果我確實解決了問題,我會在這裏發佈解決方法。 – Wilskt

+0

將其縮小到正在生成日期的查詢,後續問題在這裏如果你感興趣:) http://stackoverflow.com/questions/17195928/access-sql-given-two-dates-return-the-日期-的最先前的週期 – Wilskt

2

雖然查詢應該在他的文章,Bug: Outer join expressions retrieved wrongly的基礎上,加入類型返回NULL,艾倫·布朗狀態

「相反,它的行爲就好像[JET的查詢優化器]正在評估後的表達它已經返回了低級查詢的結果。「

因此,如果連接的右側與左側不匹配,則必須使用將計算爲Null的表達式選擇計算字段。

使用您的削減的代碼爲例:

SELECT 
Month.Chain, 
DateDiff("m",QueryDates.StartDate,QueryDates.EndDate)+1 AS CasesPerMonthPerStore 
FROM 
QueryDates, 
MonthRange; 

SELECT 
Chains.Chain, 
IIf(IsNull(ErrorQuery.Chain),Null,ErrorQuery.CasesPerMonthPerStore) 
FROM 
Chains 
LEFT JOIN 
ErrorQuery 
ON Chains.Chain=ErrorQuery.Chain;