搜索功能 - 加入具有多行和 where 子句的查找表

Posted

技术标签:

【中文标题】搜索功能 - 加入具有多行和 where 子句的查找表【英文标题】:Search Function - Join a look up table with multiple rows and where clause 【发布时间】:2015-06-16 21:42:10 【问题描述】:

我正在使用 Microsoft Access 2013 和 VBA 构建搜索功能。我的数据库有三个表,tblCandidatetblCandidateSkilllutSkill,虽然lutSkill 对本次讨论来说不是必需的,但我认为无论如何分享可能会有好处。

以下是我的表定义:

tblCandidate              tblCandidateSkill           lutSkill
----------------          -----------------           -------------
CandidateId               CandidateSkillId            SkillId          
FirstName                 CandidateId                 Name
MiddleName                SkillId                     Description
LastName                  YearsExp
etc...                 

候选人可以拥有多种技能,tblCandidateSkill 中的每条记录与lutSkill 中的一条记录相关。我创建了一个查询/视图 (viewCandidate),它连接了 tblCandidatetblCandidateSkill。这按预期工作。如果候选人具有多项技能,则每项技能都会与候选人信息一起列在单独的行中。

我在 VBA 中的搜索功能基本上只是一堆嵌套的 If Else 语句,它们会生成一些动态 SQL。

下面是我的代码,供好奇的人参考。

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,则结果不准确。

【问题讨论】:

tblCandidate 可能 应该有CandidateSkillId 列:每个候选人应该只有一行,但是通过包含CandidateSkillId 你会强迫它有>1 如果候选人有多种技能。 抱歉,打错了。现在会修复它。谢谢。 【参考方案1】:

就涉及到 SQL 而言,我希望您可以执行以下操作:

Select CandidateId, Count(*)
from viewCandidate
where CandidateSkillId in (skill1,skill2,skill3)
having count(*) = skillCt

【讨论】:

以上是关于搜索功能 - 加入具有多行和 where 子句的查找表的主要内容,如果未能解决你的问题,请参考以下文章

Where子句选择多行唯一值

两个表上的并集,其中一个带有 where 子句

使用 WHERE 和 IN 子句的 MongoDB 查询

Knex.js:加入 'select' 和 'where' 子句

在过滤器的where子句中匹配多行

如何使用 Where 子句从多个表中删除多行?