小编典典

具有多个级别的MS-Access SQL自连接

sql

我有一个表“ People”,主键为“ PersonID”,字段为“ Supervisor”。“ Supervisor”字段包含用于创建自我联接的“
PersonID”的外键。

我想创建一个sql查询,以返回所有以“
Me”(登录到数据库的PersonID)作为管理员的人,以及该列表上有人标记为管理员的任何人。本质上,我想在命令链中列出提供的PersonID下面的任何人。


阅读 263

收藏
2021-04-07

共1个答案

小编典典

考虑以下功能集:

Function BuildQuerySQL(lngsid As Long) As String
    Dim intlvl As Integer
    Dim strsel As String: strsel = selsql(intlvl)
    Dim strfrm As String: strfrm = "people as p0 "
    Dim strwhr As String: strwhr = "where p0.supervisor = " & lngsid

    While HasRecordsP(strsel & strfrm & strwhr)
        intlvl = intlvl + 1
        BuildQuerySQL = BuildQuerySQL & " union " & strsel & strfrm & strwhr
        strsel = selsql(intlvl)
        If intlvl > 1 Then
            strfrm = "(" & strfrm & ")" & frmsql(intlvl)
        Else
            strfrm = strfrm & frmsql(intlvl)
        End If
    Wend
    BuildQuerySQL = Mid(BuildQuerySQL, 8)
End Function

Function HasRecordsP(strSQL As String) As Boolean
    Dim dbs As DAO.Database
    Set dbs = CurrentDb
    With dbs.OpenRecordset(strSQL)
        HasRecordsP = Not .EOF
        .Close
    End With
    Set dbs = Nothing
End Function

Function selsql(intlvl As Integer) As String
    selsql = "select p" & intlvl & ".personid from "
End Function

Function frmsql(intlvl As Integer) As String
    frmsql = " inner join people as p" & intlvl & " on p" & intlvl - 1 & ".personid = p" & intlvl & ".supervisor "
End Function

在这里,BuildQuerySQL可以为函数提供与PersonID对应的,Supervisor并且函数将为适当的查询返回“递归”
SQL代码,以获得PersonID主管的所有下属的。

因此,可以评估该函数以构造保存的查询,例如,对于具有的主管PersonID = 5,创建名为的查询Subordinates

Sub test()
    CurrentDb.CreateQueryDef "Subordinates", BuildQuerySQL(5)
End Sub

或者根据您的应用程序的要求,对SQL进行评估以打开结果的RecordSet。

请注意,该函数构造一个UNION查询,嵌套的每个级别都与前一个查询结合在一起。

2021-04-07