2011-02-03 190 views
0

由於Where條件中的兩列(tblEventLog.PartNumberChgLvl),此查詢不起作用。 我應該如何更改查詢來解決問題?MS ACCESS查詢

strNewSql1 = _ 
    "SELECT DISTINCT " & _ 
     "tblRevRelLog_Detail.PartNumber, " & _ 
     "tblRevRelLog_Detail.ChangeLevel " & _ 
    "FROM tblRevRelLog_Detail LEFT JOIN tblEventLog " & _ 
     "ON (tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber) " & _ 
     "AND (tblEventLog.PartNumberChgLvl " & _ 
      "= tblRevRelLog_Detail.ChangeLevel) " & _ 
    "WHERE (tblEventLog.PartNumber, tblEventLog.PartNumberChgLvl) NOT IN " & _ 
     "(SELECT tblEventLog.PartNumber, tblEventLog.PartNumberChgLvl " & _ 
     "FROM tblEventLog " & _ 
     "WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper' " & _ 
      "AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber " & _ 
      "AND tblEventLog.PartNumberChgLvl " & _ 
       "= tblRevRelLog_Detail.ChangeLevel) " & _ 
     "AND tblEventLog.TrackingNumber = """ & tempTrackingNumber & """ " & _ 
     "AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber " & _ 
     "AND tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel;" 

我用一個例子來展示這個。

例如:讓我們兩個包1和2

封裝1具有A-1,B-0,C-1部分號碼與changelevels和 包2具有-1,d-1,E -1帶更改級別的零件編號

如果我從包裝1中刪除「a-1」,應該不會顯示該包裝,但應該顯示包裝2.使用此查詢它不會顯示在包裝中2也。

Reviewrelease_Form(主要形式)連接至reviewreleasetable:

此表包含基本數據和包裝器數

包裝號:RevRel_Form(子窗體)鏈接到tblRevRelLog_Detail

event_Input是窗體在這裏我們輸入事件。當我選擇一個事件時它將顯示partnumbers。這是查詢進入圖片的地方。

這不應該顯示被刪除的partnumbers。這工作正常。但是,如果具有相同changelevl的相同零件號從diff包中刪除,它也不會顯示在當前包中。

回答

0

什麼時候使用「IN」比較運算符,只能比較一個值和一組值。

所以,你需要改變的那部分你的WHERE子句:

WHERE 
tblEventLog.PartNumber NOT IN(SELECT tblEventLog.PartNumber FROM tblEventLog WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper'AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber AND tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel) and 

tblEventLog.PartNumberChgLvl NOT IN(SELECT tblEventLog.PartNumberChgLvl FROM tblEventLog WHERE tblEventLog.EventTypeSelected = 'pn REMOVED From Wrapper'AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber AND tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel) 

但是,請注意,做了兩那些「內選擇」(相關子查詢)可查詢顯著放緩。使用加入到「內部選擇」可能會更好。

+0

喜布蘭登,這並不是說慢,但仍然是拉動相同的記錄。我沒有看到任何區別.. – user397316 2011-02-03 18:25:50

+0

你有沒有試過一個緊湊和修復? – 2011-02-03 19:37:50

+0

請注意,「不在」和「不存在」不能由Jet/ACE查詢優化器進行可靠優化,並且可能不會在比較的兩側使用索引。 IN和EXISTS本身會可靠地使用雙方的索引,但NOT操作符往往會導致它失敗。可以使用JOIN來代替(總是會進行很好的優化),特別是在不需要可編輯性的情況下(如此處所示)。你沒有遇到性能問題的事實告訴我,你的後端實際上不是Jet/ACE,而是其他一些數據庫。 – 2011-02-06 00:38:33

0

在猜測,我會說,如果它已經從任何包裝中取出您的查詢,在「NOT IN」點(即其子查詢),將有效表現出任何部分號碼。這是因爲該子查詢正在搜索所有包。您需要修改它(以某種方式),以便它只考慮與感興趣的包相關的行。

仔細查看該子查詢。它將條件放在零件號,更改級別和事件類型上。但是包裹有什麼限制?它應該如何確定包1的哪些行以及包2的哪些行?

我的猜測是來自包1和包2的行混合在一起。由於它找到了一行,其中「EvtLog.EventTypeSelected ='pn REMOVED From Wrapper'」爲True對於其中至少一個這些軟件包,「NOT IN」使它成爲False無論您想要在你的事件查看器。


布蘭登S上面說了什麼(關於IN與EXISTS),再加上:您可能需要使用別名;例如(使別名EvtLog的子查詢):

"SELECT DISTINCT tblRevRelLog_Detail.PartNumber, tblRevRelLog_Detail.ChangeLevel 
FROM tblRevRelLog_Detail 
LEFT JOIN tblEventLog ON 
    (tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber) 
    AND (tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel) 
WHERE NOT EXISTS (SELECT EvtLog.PartNumber, EvtLog.PartNumberChgLvl 
    FROM tblEventLog EvtLog 
    WHERE tblEventLog.PartNumber=EvtLog.PartNumber 
    AND tblEventLog.PartNumberChgLvl=EvtLog.PartNumberChgLvl 
    AND EvtLog.EventTypeSelected = 'pn REMOVED From Wrapper' 
    AND EvtLog.PartNumber = tblRevRelLog_Detail.PartNumber 
    AND EvtLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel) 
AND tblEventLog.TrackingNumber = """ & tempTrackingNumber & """ 
AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber 
AND tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel" 
0

我看着你的查詢一點點接近。我認爲你的查詢可能比它需要的更復雜。

我覺得這個簡單的查詢可能是你以後打算什麼:

SELECT DISTINCT 
    tblRevRelLog_Detail.PartNumber, 
    tblRevRelLog_Detail.ChangeLevel 
FROM tblRevRelLog_Detail 
LEFT JOIN tblEventLog ON 
    (tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber) AND 
    (tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel) 
WHERE 
    tblEventLog.TrackingNumber = """ & tempTrackingNumber & """ 
    AND tblEventLog.PartNumber = tblRevRelLog_Detail.PartNumber 
    AND tblEventLog.PartNumberChgLvl = tblRevRelLog_Detail.ChangeLevel; 
    AND tblEventLog.EventTypeSelected <> 'pn REMOVED From Wrapper'