【问题标题】:Multiple 'AND' conditions on same column同一列上的多个“与”条件
【发布时间】:2017-10-08 02:28:18
【问题描述】:

我在 ASP.Net 中使用 Access 2007 数据库,如果项目满足多个“AND”子句,我需要从表中提取数据。

例如:

    Select * from tableA
    where tableA.column1 = myvalue1
    and (tableA.column2 = myvalue2
    and tableA.column2 = myvalue3)

('and' 子句周围的 '(' 和 ')' 括号是访问要求)

myvalue1 在 column1 中存在多次,因为 column2 为 column1 的值存储了许多不同的数据。

但是,我只希望结果显示满足所有 column2 搜索条件的 column1 值。

例如,column1 包含员工姓氏,column2 包含员工的资格。

列 1 中的一名员工可能拥有列 2 中的许多资格。

使用 'OR' 子句搜索拥有分配所需的所有资格的员工将为每个员工生成一个包含多行的表。

对于拥有每一项所需资格的每个员工,都需要一行。

假设员工 A 具有资格 X、Y 和 Z。每次将资格添加到第 2 列时,员工的姓名将在第 1 列的一行中,因此员工的姓名在第 1 列中出现 3 次。假设现在员工 B 也有资格 X、Y 和 Z,但员工 C 有 W、X 和 Y。如果分配需要资格 X、Y 和 Z,我不希望员工 C 出现在搜索结果中,因为员工 C 不会' t持有相关资格。

当我使用上面的 'select' 命令和一个 'and' 子句时,搜索工作正常,但是有两个 'and' 子句没有返回任何内容,即使我知道 column1 中的项目同时满足两个 '和'标准。

我在“and”子句的连接中遗漏了什么?

【问题讨论】:

  • 您确定不希望在第二和第三子句之间使用 OR 吗?列值几乎不可能等于两个不同的值。我想看看你的数据示例,其中 column2 = value1 和 column2 = value2
  • 可以tableA.column2 = myvalue2 AND tableA.column2 = myvalue3在同一行吗?如果没有,那么您需要在它们之间使用OR
  • 更新您的问题添加适当的数据样本和预期结果
  • 添加了更多细节和预期结果
  • 对于拥有每一项所需资格的每个员工,都需要一行。将以下内容添加到您的 SQL 中:GROUP BY column1 ORDER BY column1

标签: sql asp.net ms-access


【解决方案1】:

以下解决方案可行,但性能会受到影响。这将返回每人 1 行,我可以重写它以返回两行。

Select * from tableA
where tableA.column1 = myvalue1
and (tableA.column2 = myvalue2
and DCount("column2", "TableA", "column1 = """ & column1 & """ AND column2 = """ & myvalue3 & """" ) <> 0)

您的基本问题是没有 group by 或 pivot 子句的 select 查询一次只能评估 1 行。我可能会旋转数据,连接它,然后最终评估它以获得更好的性能。但这更复杂,需要有关表结构和您想要做什么的更多信息。

【讨论】:

  • 感谢 Erik,我使用了 Johnny 答案的变体来获得可行的解决方案(请参阅我在页面其他地方的答案)。与此同时,我也会尝试你的方法,看看开销是否更低..
【解决方案2】:

根据新的信息,我将提交这个答案:

我的直觉是,你不能在一个简单的查询中做到这一点。这听起来很笨拙,但我认为您将需要创建一个查询,即 SELECT DISTINCT 查询,并且该查询将为每个员工提取一条记录:

Select DISTINCT Column1 from tableA

将此查询称为 qryEmployees

接下来您需要创建一个新表。称之为 tblQualifications。它将包含 2 个字段; EName 和 EQualifications。我们将在一分钟内完成。

接下来,您需要遍历 qryEmployees 中的每条记录,并将员工姓名及其资格写入 tblQualifications。

'Run through every Employee name
Do While qryEmployees.EOF = False
  'Set up a temp variable, MyQual, and set it equal to Empty
  MyQual = ""
  'Pull all qualifications from TableA for the current Employee
  Set rec = db.OpenRecordset ("Select Column1, column2 from TableA WHERE Column1 = '" & qryEmployees.Column1 & "'")
  'Looping through the qualifications
  Do While rec.EOF = False
    'Add the qualification to the MyQual string
    MyQual = MyQual & rec("Column2") & ", "
    rec.MoveNext
  Loop

  'Now that we have all the qualifications in a string, trim off the last ", "
  MyQual = left(MyQual, len(MyQual)-2)

  'Open up tblQualifications and fill it with the Employee and a string of all of their qualifications
  tblQualifications.AddNew
    tblQualifications(0) = qryEmployees.Column1
    tblQualifications(1) = MyQual
  tblQualifications.Update

'Move on to the next Employee and repeat the process
qryEmployees.MoveNext
Loop

现在您有一张表,其中一个字段包含员工姓名,下一个字段包含他的所有资格。如果您在此表上使用 LIKE 运算符,您应该会得到结果。

Select * from tblQualifications
where tblQualifications.EName = myvalue1
and (tblQualifications.EQualifications LIKE myvalue2
and tblQualifications.EQualifications LIKE myvalue3)

它不漂亮,但它会起作用(上面的代码有点令人费解,因为我把它写在我的脑海中并且它未经测试)。

【讨论】:

    【解决方案3】:

    感谢 Johnny,您的建议启发了我编写一个稍微不同的解决方案方法。

    我将“AND”替换为“OR”,因为其他人建议将任何具有任何资格的员工提取到表中。

    结果是一个表格,其中包含每个具有这些资格之一的员工所需的资格。

    然后我在别处计算了该任务所需的资格数量,并将其与员工是否具有所需的资格数量进行比较,如下所示:

        Dim objSearchTable As DataTable = DSSearch.Tables("Employees")
    
        Dim i As Integer
    
        If QualificationsCount > 0 Then
    
            For i = 0 To objSearchTable.rows.count - 1
    
                strEmployee = objSearchTable.Rows(i).Item("column1")
    
                Dim foundRows As DataRow() = objSearchTable.[Select]("column1 = '" & strEmployee & "'")
    
                Dim numberOfRecords As Integer = foundRows.count
    
                If numberOfRecords < QualificationsCount Then
    
                    objSearchTable.Rows(i).Delete
    
                End If
    
            Next
    
        End If
    
        objSearchTable.AcceptChanges
    

    如果资格数少于要求的数量,这将从表中删除员工的每个实例。

    该解决方案并不像一开始只从数据库中提取正确的员工那样优雅。

    从数据库中提取每个员工也有开销,但最终结果是一个表,每个员工只有一行,具有所有资格,这可以满足我的需要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2021-12-13
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多