我遇到了一個問題,我們有3個表。 如果供應倉庫沒有該項目(刪除),或者沒有設置,它應該顯示,但是根據源矩陣它應該是供應倉庫。MS Access SQL連接問題在「重複」查詢的情況下
簡化佈局應該看起來像這樣。
表MainData
- 領域ITEMNO - 個人標識符,沒有重複(PK)
- 領域的ItemType - 有一定的選擇,我必須過濾一些 特定值。
表WarehouseData
- 領域ITEMNO - 與MainData有關,但PK與下一個場組合
- 領域ItemLocation - 給出具有貨號描述的這樣的物品的一個特定位置
- 字段商品分類 - 需要加入SourceWHMatrix
- 場ItemDeleted - 這是一個char場(因爲出口數據),如果該項目被 「刪除」 的值是 'X',否則空
表SourceWHMatrix(不是空的!)
- 領域ItemLocation - 前兩個字段是主鍵
- 領域ItemCategory
- 場SourceLocation - 它應該給地方的項目將交付
我需要檢查以下內容: 如果貨號屬於某些ItemType的(MainData表)和ItemDeleted是空然後是否這商品編號是在來源地(這是由確定來源WHMa trix基於商品位置AND商品分類)。必須列出的所有貨號這是「被刪除」在SourceLocation(在這種情況下,表WarehouseData場ItemLocation被檢查返回SourceLocation值)OR甚至沒有setupped這樣的位置。
注:在同一情況下貨號針對不同ItemLocation,ItemCategory並不總是一致的。並且每個ItemLocation有許多不同的ItemCategory來確定源倉庫。
我嘗試了很多LEFT JOIN組合,但似乎我無法列出那些沒有設置的值。 (通過創建一個WarehouseData的重複表格,我可以在提供倉庫時列出已刪除的項目。)另外,我可以在VBA中用ADODB做到這一點,但是我想將所有內容保留在SQL代碼中,甚至不使用自定義函數。它在Access 2010中,在其JET SQL引擎上運行。
這是行不通當前查詢
SELECT MD.itemno,
MD.itemtype,
WD.itemlocation,
SMat.sourcelocation, --this could be empty
WD.itemdeleted AS "SourceWHDelFlag"
FROM maindata AS MD
INNER JOIN (warehousedata AS WD
INNER JOIN (sourcewhmatrix AS SMat
LEFT JOIN wd
ON SMat.sourcelocation = WD.itemlocation)
ON (WD.itemlocation = SMat.itemlocation
AND WD.itemcategory = SMat.itemcategory))
ON MD.itemno = WD.itemno
WHERE (MD.itemtype = 'Value1'
OR MD.itemtype = 'Value2')
這是我可以經過進一步的思考上來。然而,現在在我的i5上運行20分鐘的查詢。所以這不是最優的,而且當我可以檢查Access的一些預結果時,似乎是將別名的語句添加到造成錯誤的where子句中,因爲不再在同一個where子句中的其他字段上正確地過濾。所以這是我的「解決方案」:
SELECT MD.ItemNo,
MD.ItemType
WD.itemlocation,
SMat.sourcelocation, --this could be empty
(SELECT WD.ItemDeleted FROM WD WHERE WD.ItemNo = MD.ItemNo) AS "SourceWHDelFlag"
FROM MainData AS MD INNER JOIN (WarehouseData AS WD
LEFT JOIN SourceWHMatrix AS SMat
ON (WD.ItemLocation = SMat.ItemLocation
AND WD.ItemCategory = SMat.ItemCategory))
ON MD.ItemNo = WD.ItemNo
WHERE (MD.ItemType = 'Value1' OR MD.ItemType = 'Value2')
AND WD.ItemDeleted Is Null
AND WD.ItemCategory Is Not Null
AND WD.ItemCategory Not Like '##' -- This is another filter value, and it seems to be buggy
-- with SELECT clause in WHERE statement
AND (SELECT WD.ItemDeleted FROM WD WHERE WD.ItemNo = MD.ItemNo) Is Not Null
感謝您的幫助提前!
UPDATE 我做了一些VBA,這段代碼實際上工作。我在代碼中評論了所有必要的信息,但它仍然很慢。 (如果你有一個想法讓它在合理的時間內運行得更快,我可以爲它開放。)200條記錄花費了大約10分鐘,因此在16-17萬條記錄上運行需要15個小時。我可以在Excel中一些VLOOKUP做到這一點在Excel快得多......
Private Sub Command0_Click()
'initialize variables
Dim connDB As ADODB.Connection
Dim filtRecSet As ADODB.Recordset
Dim tmpRecSet As ADODB.Recordset
Dim tmpLineText As String
Dim tmpCounter As Integer
Dim filePath As String
Dim tmpFSO As New FileSystemObject
Dim tmpStream As TextStream
Dim startTime, endTime As Double
'set values
Set connDB = New ADODB.Connection
Set connDB = CurrentProject.Connection
Set filtRecSet = New ADODB.Recordset
Set tmpRecSet = New ADODB.Recordset
filePath = "C:\data\output.txt"
Set tmpStream = tmpFSO.CreateTextFile(filePath, True)
startTime = Now()
'this is a test database
'I previously deleted all not required MD.ItemType to test speed of SQL queries
'it's the reason for no filtering on MD.ItemType
'open base recordset, which are not deleted (WD.ItemDeleted)
'and belong tospecific MD.ItemType values
'and can match certain filters on WD.ItemCategory
With filtRecSet
.ActiveConnection = connDB
.Source = "SELECT MD.ItemNo, WD.ItemLocation, MD.ItemType, WD.ItemCategory, SMat.SourceLocation FROM MainData As MD INNER JOIN (WarehouseData As WD LEFT JOIN SourcwWHMatrix As SMat ON (WD.ItemLocation = SMat.ItemLocation AND WD.ItemCategory = SMat.ItemCategory)) ON MD.ItemNo = WD.ItemNo WHERE WD.ItemCategory Is Not Null AND WD.ItemCategory Not Like '[0-9][0-9]' AND WD.ItemDeleted Is Null"
.LockType = adLockOptimistic
.CursorType = adUseClient
End With
'RecordCount: 16610
'open control recordset for all appropiate MD.ItemType
With tmpRecSet
.ActiveConnection = connDB
.Source = "SELECT MD.ItemNo, WD.ItemLocation, MD.ItemType, WD.ItemCategory, SMat.SourceLocation FROM MainData As MD INNER JOIN (WarehouseData As WD LEFT JOIN SourcwWHMatrix As SMat ON (WD.ItemLocation = SMat.ItemLocation AND WD.ItemCategory = SMat.ItemCategory)) ON MD.ItemNo = WD.ItemNo"
.LockType = adLockOptimistic
.CursorType = adUseClient
.Filter = adFilterNone
End With
'RecordCount: 138713
filtRecSet.Open
'tmp variable to see how many records have been processed
tmpCounter = 1
If Not filtRecSet.EOF Then
'select first record
filtRecSet.MoveFirst
Do While Not filtRecSet.EOF
'find SourceLocation
tmpRecSet.Filter = "MATNR = '" & filtRecSet(0).Value & "' AND WERKS = '" & filtRecSet(5).Value & "'"
tmpRecSet.Open
'check how many records in recordset; there should not be more than one, that's why it considered as error
If tmpRecSet.RecordCount = 1 Then
tmpRecSet.MoveFirst
tmpLineText = filtRecSet(0).Value & "|" & filtRecSet(1).Value & "|" & filtRecSet(2).Value & "|" & filtRecSet(3).Value & "|" & filtRecSet(4).Value & "|" & filtRecSet(5).Value & "|" & tmpRecSet(3).Value
ElseIf tmpRecSet.RecordCount > 1 Then
tmpLineText = "ERROR"
'in case EOF is True -> no records
Else
tmpLineText = filtRecSet(0).Value & "|" & filtRecSet(1).Value & "|" & filtRecSet(2).Value & "|" & filtRecSet(3).Value & "|" & filtRecSet(4).Value & "|" & filtRecSet(5).Value & "|"
End If
Debug.Print "Record no.: " & tmpCounter
'write out text file
tmpStream.WriteLine tmpLineText
filtRecSet.MoveNext
tmpRecSet.Close
tmpCounter = tmpCounter + 1
Loop
End If
tmpStream.Close
endTime = Now()
Debug.Print "Elapsed time: " & CStr((endTime - startTime) * 24 * 60 * 60) & " seconds."
End Sub
它可能是你的一些有條件的地方,應放在LEFT JOIN。令人遺憾的是,您的要求的文字描述太難以解析。例如,那麼是否很難遵循。也許你可以編輯你的問題,使它更簡潔一些。例如一個項目符號列表。 – 2013-03-19 17:17:23
感謝您的回覆康萊德。 – szucsitg 2013-03-19 17:26:48
它應該看起來像這樣,希望我沒有搞砸任何事情: SELECT MD.ItemNo,MD.ItemType,WD.ItemLocation,SMat.SourceLocation - >這可能是空的,WD.ItemDeleted AS「SourceWHDelFlag」 - >這應該來自WD表檢查時SourceLocation = ItemLocation FROM MainData AS MD INNER JOIN(WarehouseData AS WD INNER JOIN(SourceWHMatrix AS SMat LEFT JOIN WD ON SMat.SourceLocation = WD.ItemLocation)ON(WD.ItemLocation = SMat .ItemLocation AND WD.ItemCategory = SMat.ItemCategory)ON MD.ItemNo = WD.ItemNo。 – szucsitg 2013-03-19 17:41:22