我正在使用Microsoft Access 2013和VBA构建搜索功能。我的数据库有三个表,tblCandidate
,tblCandidateSkill
,lutSkill
,虽然lutSkill
对于这次讨论来说并不是必需的,但我认为无论如何分享可能都是有益的。
以下是我的表格定义:
tblCandidate tblCandidateSkill lutSkill
---------------- ----------------- -------------
CandidateId CandidateSkillId SkillId
FirstName CandidateId Name
MiddleName SkillId Description
LastName YearsExp
etc...
候选人可以拥有多种技能,tblCandidateSkill
中的每个记录都与lutSkill
中的单个记录相关。我创建了一个加入viewCandidate
和tblCandidate
的查询/视图(tblCandidateSkill
)。这按预期工作。如果候选人具有多种技能,则每项技能与候选人信息一起列在单独的行中。
我在VBA中的搜索功能基本上只是一堆生成动态SQL的嵌套If Else
语句。
以下是我的好奇代码。
Private Sub Search_Click()
' Declare variables
Dim stateId As Integer
Dim skillId1 As Integer
Dim skillId2 As Integer
Dim skillId3 As Integer
Dim yearsExp1 As Integer
Dim yearsExp2 As Integer
Dim yearsExp3 As Integer
Dim count As Integer
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strQuery As String
Dim strWhere As String
Dim strSQL As String
On Error GoTo errHandler
strQuery = "qryCandidateSearchResults"
strSQL = "SELECT FirstName, MiddleName, LastName, Phone, Email FROM viewCandidate WHERE "
'===========================================================
' Start dynamic query
' Check for state id
If Not IsNull(Me.ddlState.Value) Then
strWhere = strWhere & " ([StateId] = " & Me.ddlState.Column(0) & ") AND "
End If
' Check for skillId1 and yearsExp1
If Not IsNull(Me.ddlSkill1.Value) Then
' if yearsExp1 is not null, include it,
' otherwise dont.
If Not IsNull(Me.ddlYearsExp1.Value) Then
strWhere = strWhere & " (SkillId = " & Me.ddlSkill1.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp1.Column(0) & ") AND "
Else
strWhere = strWhere & " (SkillId = " & Me.ddlSkill1.Column(0) & ") AND "
End If
End If
' Check for skillId2 and yearsExp2
If Not IsNull(Me.ddlSkill2.Value) Then
If Not IsNull(Me.ddlYearsExp2.Value) Then
strWhere = strWhere & " (SkillId = " & Me.ddlSkill2.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp2.Column(0) & ") AND "
Else
strWhere = strWhere & " (SkillId = " & Me.ddlSkill2.Column(0) & ") AND "
End If
End If
' Check for skillId3 and yearsExp4
If Not IsNull(Me.ddlSkill3.Value) Then
If Not IsNull(Me.ddlYearsExp3.Value) Then
strWhere = strWhere & " (SkillId = " & Me.ddlSkill3.Column(0) & " AND YearsExp >= " & Me.ddlYearsExp3.Column(0) & ") AND "
Else
strWhere = strWhere & " (SkillId = " & Me.ddlSkill3.Column(0) & ") AND "
End If
End If
'============================================================
' Remove the last "AND"
If Right(strWhere, 4) = "AND " Then
strWhere = Mid(strWhere, 1, Len(strWhere) - 4)
End If
strSQL = strSQL & strWhere
' Check for criteria and exit if none exists
' else set CurrentDb, QueryDef and SQL string
If Len(strWhere) = 0 Then
MsgBox "You didn't enter any criteria for this report, now exiting", vbExclamation
Exit Sub
Else
Set db = CurrentDb
Set qdf = db.QueryDefs(strQuery)
qdf.SQL = strSQL
End If
DoCmd.OpenReport "rptCandidateSearch", acViewPreview
Debug.Print strSQL
Exit Sub
errHandler:
Select Case Err.Number
Case 2501
'No data
Resume Next
Case Else
MsgBox Err.Number & " - " & Err.Description
End Select
End Sub
我的问题源于每个技能在一个单独的行上。例如,如果我想在数据库中搜索具有三种技能的候选人,那么如何过滤该数据以仅显示符合搜索条件的候选人?我的所有尝试都失败了,因为每个skillId都列在一个单独的行上。如果我在where子句中使用And
,则没有任何捕获,如果我使用OR
,则结果不准确。
答案 0 :(得分:0)
就涉及SQL而言,我希望你能做的事情是:
Select CandidateId, Count(*)
from viewCandidate
where CandidateSkillId in (skill1,skill2,skill3)
having count(*) = skillCt