繁体   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