簡體   English   中英

Access SQL:根據條件更新一對多關系中的子項

[英]Access SQL: Updating Children in a 1 to Many relationship based on criteria

我的問題是一個 1-Many 關系,其中孩子存儲在 1 ChildTable 上,

 ChildID | ParentID | Data2 | InputDate 
 ------------------------------------
  1      |  345     |   100 | 3-5-2016
  2      |  345     |   0   | 3-12-2016
  3      |  345     |  150  | 3-19-2016
  4      |  345     |   0   | 4-20-2016
 ... more children with different parent IDs

並且還考慮到父母存儲在他們自己的 ParentTable 中,帶有 ParentID... 數據等。

我的問題是一個分區或更新如何查詢類似的數據庫,以便如果數據列的值為 0,則它會使用最后一個輸入數據進行更新。 (假設網絡爬蟲未能提取數據,我想進行近似分析)。 原始數據不必在基表上更新,也可以在拉取它的查詢中更新。 我相信有一種方法可以使用 SQL 來實現這一點。 我的嘗試非常緩慢,並且由於未知原因沒有奏效。

我嘗試編寫一些 VBA-Access 代碼來遍歷平面文件 ChildTable + ParentTable 並使用 SQL 查找更新列數據中的每個 0 值單元格。 如果單元格 = 0,則轉到最后一個非零的可用數據。 這需要數年才能運行的問題。

Option Compare Database

Sub SoldOut()
On Error GoTo ProcError
Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset("MainDataTable") 'This is the flat file version of the data above

'Check to see if the recordset actually contains rows
If Not (rs.EOF And rs.BOF) Then
    rs.MoveLast
    rs.MoveFirst 'Unnecessary in this case, but still a good habit
    Do Until rs.EOF = True
    GetLastWeek = 0
        If Not rs("Data") > 0 Then
            rs.Edit
            rs("Data") = GetLastWeek(rs('ChildID'), rs('ParentID'), rs('Data'), rs('InputDate'))
            rs.Update
        End If

        'Move to the next record. Don't ever forget to do this.
        rs.MoveNext
    Loop
Else
    MsgBox "There are no records in the recordset."
End If

ProcExit:
On Error Resume Next
rs.Close 'Close the recordset
Set rs = Nothing 'Clean up
Exit Sub

ProcError:
    MsgBox Err.Description
    Resume ProcExit

End Sub

Private Function GetLastWeek(ChildID, ParentID As Long, InputDate As Date) As Integer
    'given a record it looks up the weeks before and returns it if it exists
    Dim rst As DAO.Recordset, strSQL As String, rc As Integer ' SQL Code for seeing if last week's data exists.

    strSQL = "SELECT * " & _
    "FROM MainDataTable " & _
    "WHERE MainDataTable.[ParentId] = " & ParentID & "AND MainDataTable.[InputDate] <# " & InputDate & "AND NOT MainDataTable.[Data] = 0 
    ORDER BY MainDataTable.[InputDate] DESC;"

    Set rst = CurrentDb.OpenRecordset(strSQL): rst.MoveLast: rst.MoveFirst
    rc = rst.RecordCount
    If rc = 0 Then GoTo Cleanup 'if no record, then we are out of luck
    If rc > 0 Then 'If there's some Record
        Do Until rs.EOF = True Or GetLastWeek > 0
            Dim price As Integer: price = rst("Data")
            If price > 0 Then: GetLastWeek = price
            rs.MoveNext
        Loop
    End If

Cleanup:
    rst.Close
    Set rst = Nothing
    If GetLastWeek = 0 Then GetLastWeek = 1 '1 means no data was found
    'Set so the output if nothing is found to 1 so that the code doesn't have to run on the same rows every single week
End Function

我不確定你有什么可以工作,但你應該做的就是遍歷按parentid, date asc排序的主表parentid, date asc ,然后保存 parentID 和數據值以供下一次迭代使用( Dim lDataValPrev as long ) 只要它不為零。 如果當前數據值為零且 parentID 未更改,請將其替換為您存儲的先前值。 您應該只需要瀏覽一次您的數據,無需額外調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM