小编典典

Advanced (?) AND / OR 查询

sql

对于相当简单的表结构,即。 ie. Person, Criteria, and PersonCriteria (the combi-table),我现在设置了一个查询,以选择具有所有选定条件的所有人员。

此刻查询本身看起来像这样:

SELECT 
  p.PersonID   
FROM 
  Person p,     
  ( SELECT DISTINCT PersonID, CriteriaID 
    FROM PersonCriteria 
    WHERE CriteriaID in (#list_of_ids#)     
  ) k     
WHERE 
  p.PersonID= k.PersonID     
GROUP BY 
  p.PersonID     
HAVING 
  Count(*) = #Listlength of list_of_ids#

到目前为止,没有问题,一切正常。

现在,我想为用户提供在搜索中添加一些AND和OR变量的可能性。有人会说:

我正在寻找一个拥有以下条件的人:条件1 AND 3 AND 4(上面的查询将涵盖该条件)AND(5 OR 6 OR 7)AND(8 OR
9),依此类推…

我不确定从哪里开始。我希望其他人也可以.. :-)


阅读 370

收藏
2021-04-28

共1个答案

小编典典

我不得不说-我很困惑。我想不出任何解决方案,甚至会接近。我会尝试在这些方向上寻找解决方案:

  • 用户定义的聚合函数。也许您可以创建一个函数,该函数将所需的表达式(以简化的语法)和单个人的行作为参数。然后,该函数解析表达式并将其与行进行匹配。嗯…也许MySQL包含一些串联聚合函数和regex匹配函数?那么,这可能是一个解决方案(尽管可能不是非常快的解决方案)。
  • 分析功能。我不假装自己理解它们,但是据我所知,我认为它们通常都朝着这个方向发展。尽管我不知道是否会有适合该需求的功能。

补充: 啊,我想我明白了!虽然我认为演出会很惨。但这行得通!例如,如果您需要搜索,1 AND 2 AND (3 OR 4)则可以编写:

SELECT
    *
FROM
    Persons A
WHERE
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=1)
    AND
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=2)
    AND
    (
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=3)
        OR
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=4)
    )

补充2: 这是另一个,尽管性能可能会更差:

SELECT p.* FROM Person p
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=1) c1 ON p.PersonID=c1.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=2) c2 ON p.PersonID=c2.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID IN (3,4)) c3 ON p.PersonID=c3.PersonID

补充3: 这是2号的变体,但实际上可能会有不错的表现!

SELECT p.* FROM
    Person p
    JOIN PersonCriteria c1 on (p.PersonID=c1.PersonID AND c1.CriteriaID=1)
    JOIN PersonCriteria c2 on (p.PersonID=c2.PersonID AND c2.CriteriaID=2)
    JOIN PersonCriteria c3 on (p.PersonID=c3.PersonID AND c3.CriteriaID IN (3,4))

如果您向列(PersonID,CriteriaID)上的PersonCriteria添加一个索引(正是按此顺序!),那么我认为它无论如何都将与您获得的速度一样快。

2021-04-28